/* eslint-disable */
import m3 from "./m3.js";
import webglUtils from "./webgl-utils.js";
import waterColor from "./waterColor";

const Chart = function () {
  let _gl;
  let _textCtx;
  let _config;
  let _container;
  let _textcontainer;

  let containerWidth = null;
  let containerHeight = null;

  // 着色器相关变量
  let _pointShaderProgram;
  let _pointPositionAttributeLocation;
  let _pointSizeAttributeLocation;
  let _pointFragColor;
  let _pointMatrixLocation;

  let _lineShaderProgram;
  let _linePositionAttributeLocation;
  let _lineFragColor;
  let _linematrixLocation;

  let _lineShaderProgramUseVaringColor;
  let _linePositionAttributeLocationUseVaringColor;
  let _lineColorAttributeLocationUseVaringColor;
  let _linematrixLocationUseVaringColor;

  let _imageProgram;
  let _imagePositionAttributeLocation;
  let _imageTexcoordAttributeLocation;
  let _imageMatrixLocation;
  let _imgTexure;

  let _buffer = null;
  let _buffer2 = null;

  let _imageList = [];

  let _axisMatrix;
  // let _linesMatrix

  // 鼠标是否按下
  let _isMouseDown = false;
  // 记录鼠标点击开始位置
  let _mouseDownStart;
  let _lastMousePosition = null;
  let _isClickMarkLine = false;
  let _isClickMouseStrapMeasure = false;
  let _clickedMarkLine = null;
  let _clickedMarkLineSeries = null;

  let _isClickMeasureZone = false;
  let _clickedMeasureZone = null;
  let _clickedMeasureZoneSeries = null;

  let _isClickToDragMeasureZone = false;
  let _clickedToDragMeasureZone = null;

  let _onclickTimer = null;
  let _isClickYaxisPadding = false;
  let _isClickXaxisPadding = false;
  let _clickedYaxisSeries = null;
  let _clickedXaxisSeries = null;
  let _mouseMovePre = null;
  let _markIdIdx = 1;

  /**
   * 瀑布图每张图片最大宽度（如果数据点数超过这个宽度，则拆分成多张图片）
   */
  const _maxPointNum = 8000;

  const _compassConfig = {
    // 罗盘刻度的偏移角度
    compassScaleRotation: null,
    // 罗盘指针初始偏移角度
    compassPointOldRotation: null,
    // 罗盘指针当前偏移角度
    compassPointRotation: null,
    // 罗盘测量事件监听器
    compassMeasureListener: null,
    // 是否点击了罗盘指针
    isClickCompassPoint: false,
    // 罗盘matrix
    compassMatrix: null,
    // 罗盘指针matrix
    compassPointMatrix: null,
    // 之前的角度
    preJiaotdu: null,
    // 鼠标拖拽总角度变化差值
    totalJiaoDuChange: null,
    // 鼠标拖拽的扇形的数组
    sectorPoints: [],
    comapssPoints: [],
    comapssPointsSizes: [],
    // 需要显示的点的数组
    comapssShowPoints: [],
    // 需要显示的点的大小数组
    compassShowPointSizes: [],
    // 点的大小
    pointSize: 5,
    // 显示点开始角度和显示点的结束角度间的差值
    pointShowJiaoDuChange: null,
    // 置信度
    confidence: null,
    // 车位角度
    compassCarPositionRotation: null,
    // 车位matrix
    compassCarPositionMatrix: null,
    backgroundColor: null,
    wordColor: null,
  };

  const _Series = [];

  // 节流函数
  function throttle(func, timeout) {
    let timer;
    return function () {
      if (timer) {
        return;
      }
      timer = setTimeout(() => {
        timer = null;
        func.apply(this, Array.from(arguments));
      }, timeout);
    };
  }

  // 准备WebGL上下文
  function _prepareContext() {
    const DPR = window.devicePixelRatio;
    // 使用Canvas
    const div = _config.container;
    div.addEventListener("contextmenu", (event) => {
      event.preventDefault();
    });

    containerWidth = div.clientWidth;
    containerHeight = div.clientHeight;
    const webGlCanvasNode = document.createElement("canvas");
    div.appendChild(webGlCanvasNode);
    const textCanvasNode = document.createElement("canvas");
    div.appendChild(textCanvasNode);

    webGlCanvasNode.style.width = "100%";
    webGlCanvasNode.style.height = "100%";
    webGlCanvasNode.width = div.clientWidth;
    webGlCanvasNode.height = div.clientHeight;
    _container = webGlCanvasNode;
    _textcontainer = textCanvasNode;
    div.style.position = "relative";
    textCanvasNode.style.backgroundColor = "transparent";
    textCanvasNode.style.position = "absolute";
    textCanvasNode.style.left = "0px";
    textCanvasNode.style.top = "0px";
    textCanvasNode.style.zIndex = "2";
    textCanvasNode.style.width = "100%";
    textCanvasNode.style.height = "100%";
    textCanvasNode.width = div.clientWidth;
    textCanvasNode.height = div.clientHeight;
    _gl = _container.getContext("webgl", {
      preserveDrawingBuffer: true,
      antialias: true,
      antialiasSamples: 8,
    });

    _textCtx = _textcontainer.getContext("2d");
    // 清空二维画布
    _textCtx.clearRect(0, 0, _container.width, _container.height);
    if (!_gl) {
      // console.log('无法使用WebGL！')
    } else {
      // //console.log(_gl)
    }
  }

  function _initGl() {
    // 环境上下文准备
    _prepareContext();

    // 编译
    const pointVertexShader = _setupShader(
      _gl,
      _gl.VERTEX_SHADER,
      pointVertexShaderSource
    );
    const pointFragmentShader = _setupShader(
      _gl,
      _gl.FRAGMENT_SHADER,
      pointFragmentShaderSource
    );

    // 链接
    _pointShaderProgram = linkShader(
      _gl,
      pointVertexShader,
      pointFragmentShader
    );
    _pointPositionAttributeLocation = _gl.getAttribLocation(
      _pointShaderProgram,
      "a_position"
    );
    _pointSizeAttributeLocation = _gl.getAttribLocation(
      _pointShaderProgram,
      "a_PointSize"
    );
    _pointMatrixLocation = _gl.getUniformLocation(
      _pointShaderProgram,
      "matrix"
    );

    // 获取u_FragColor变量的存储位置
    _pointFragColor = _gl.getUniformLocation(
      _pointShaderProgram,
      "u_FragColor"
    );

    // 编译
    const lineVertexShader = _setupShader(
      _gl,
      _gl.VERTEX_SHADER,
      lineVertexShaderSource
    );
    const lineFragmentShader = _setupShader(
      _gl,
      _gl.FRAGMENT_SHADER,
      lineFragmentShaderSource
    );

    // 链接
    _lineShaderProgram = linkShader(_gl, lineVertexShader, lineFragmentShader);
    _linePositionAttributeLocation = _gl.getAttribLocation(
      _lineShaderProgram,
      "a_position"
    );

    // 获取u_FragColor,matrix变量的存储位置
    _lineFragColor = _gl.getUniformLocation(_lineShaderProgram, "u_FragColor");
    _linematrixLocation = _gl.getUniformLocation(_lineShaderProgram, "matrix");

    // 编译
    const imageVertexShader = _setupShader(
      _gl,
      _gl.VERTEX_SHADER,
      imgVertexShaderSource
    );
    const imageFragmentShader = _setupShader(
      _gl,
      _gl.FRAGMENT_SHADER,
      imgFragmentShaderSource
    );

    // 链接
    _imageProgram = linkShader(_gl, imageVertexShader, imageFragmentShader);
    _imagePositionAttributeLocation = _gl.getAttribLocation(
      _imageProgram,
      "a_position"
    );
    _imageTexcoordAttributeLocation = _gl.getAttribLocation(
      _imageProgram,
      "a_texCoord"
    );

    // u_matrix
    _imageMatrixLocation = _gl.getUniformLocation(_imageProgram, "u_matrix");

    // 编译
    const lineVertexShaderUseVaringColor = _setupShader(
      _gl,
      _gl.VERTEX_SHADER,
      lineVertexShaderSourceUseVaringColor
    );
    const lineFragmentShaderUseVaringColor = _setupShader(
      _gl,
      _gl.FRAGMENT_SHADER,
      lineFragmentShaderSourceUseVaringColor
    );

    // 链接
    _lineShaderProgramUseVaringColor = linkShader(
      _gl,
      lineVertexShaderUseVaringColor,
      lineFragmentShaderUseVaringColor
    );

    _linePositionAttributeLocationUseVaringColor = _gl.getAttribLocation(
      _lineShaderProgramUseVaringColor,
      "a_position"
    );
    _lineColorAttributeLocationUseVaringColor = _gl.getAttribLocation(
      _lineShaderProgramUseVaringColor,
      "a_color"
    );

    // 获取matrix变量的存储位置
    _linematrixLocationUseVaringColor = _gl.getUniformLocation(
      _lineShaderProgramUseVaringColor,
      "matrix"
    );
  }

  /**
   * 编译着色器
   * @param {*} gl
   * @param {*} type
   * @param {*} source
   * @returns
   */
  function _setupShader(gl, type, source) {
    const shader = gl.createShader(type);
    gl.shaderSource(shader, source);
    gl.compileShader(shader);

    const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    if (success) {
      return shader;
    }

    // console.log(gl.getShaderInfoLog(shader))
    gl.deleteShader(shader);
  }
  /**
   *  链接着色器
   * @param {*} gl
   * @param {*} vertexShader
   * @param {*} fragmentShader
   * @returns
   */
  function linkShader(gl, vertexShader, fragmentShader) {
    const program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    const success = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (success) {
      return program;
    }

    // console.log(gl.getProgramInfoLog(program))
    gl.deleteProgram(program);
  }
  /**
   * 创建缓冲区，并填入顶点数据
   * @param {*} data
   */
  function _createBuffer(data) {
    if (!_buffer) {
      _buffer = _gl.createBuffer();
    }
    _gl.bindBuffer(_gl.ARRAY_BUFFER, _buffer);
    _gl.bufferData(_gl.ARRAY_BUFFER, new Float32Array(data), _gl.STATIC_DRAW);
    return _buffer;
  }

  function _createBuffer2(data) {
    if (!_buffer2) {
      _buffer2 = _gl.createBuffer();
    }
    _gl.bindBuffer(_gl.ARRAY_BUFFER, _buffer2);
    _gl.bufferData(_gl.ARRAY_BUFFER, new Float32Array(data), _gl.STATIC_DRAW);
    return _buffer2;
  }

  /**
   * 绘制线段组
   * @param {*} points 点数据
   * @param {*} matirx 变换矩阵
   * @param {*} color 颜色
   */
  function _drawLineGroup(points, matirx, color) {
    _createBuffer(points);
    _gl.useProgram(_lineShaderProgram);
    _gl.enableVertexAttribArray(_linePositionAttributeLocation);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _linePositionAttributeLocation,
      2,
      _gl.FLOAT,
      false,
      0,
      0
    );

    // 设置颜色
    _gl.uniform4f(_lineFragColor, color.r, color.g, color.b, 1);

    // 设置变换矩阵
    _gl.uniformMatrix3fv(_linematrixLocation, false, matirx);
    _gl.drawArrays(_gl.LINES, 0, points.length / 2);
  }

  /**
   * 绘制线段组
   * @param {*} points 点数据
   * @param {*} matirx 变换矩阵
   * @param {*} color 颜色
   */
  function _drawLineGroupWithLineStrip(points, matirx, color) {
    _createBuffer(points);
    _gl.useProgram(_lineShaderProgram);
    _gl.enableVertexAttribArray(_linePositionAttributeLocation);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _linePositionAttributeLocation,
      2,
      _gl.FLOAT,
      false,
      0,
      0
    );

    // 设置颜色
    _gl.uniform4f(_lineFragColor, color.r, color.g, color.b, 1);

    // 设置变换矩阵
    _gl.uniformMatrix3fv(_linematrixLocation, false, matirx);
    _gl.drawArrays(_gl.LINE_STRIP, 0, points.length / 2);
  }

  /**
   * 绘制线段组,每个点单独设置颜色
   * @param {*} points 点数据
   * @param {*} matirx 变换矩阵
   * @param {*} color 颜色
   */
  function _drawLineGroupWithVaringColor(points, matirx, colors) {
    _createBuffer(points);
    _gl.useProgram(_lineShaderProgramUseVaringColor);
    _gl.enableVertexAttribArray(_linePositionAttributeLocationUseVaringColor);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _linePositionAttributeLocationUseVaringColor,
      2,
      _gl.FLOAT,
      false,
      0,
      0
    );

    // 设置颜色
    _createBuffer(colors);
    _gl.enableVertexAttribArray(_lineColorAttributeLocationUseVaringColor);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _lineColorAttributeLocationUseVaringColor,
      4,
      _gl.FLOAT,
      false,
      0,
      0
    );

    // 设置变换矩阵
    _gl.uniformMatrix3fv(_linematrixLocationUseVaringColor, false, matirx);
    _gl.drawArrays(_gl.LINES, 0, points.length / 2);
  }

  /**
   * 绘制沿x轴方向的有宽度的直线
   * @param {*} x1
   * @param {*} y1
   * @param {*} x2
   * @param {*} y2
   * @param {*} width
   * @param {*} matrix
   * @param {*} color
   */
  function _drawXLineWithWidth(x1, y1, x2, y2, width, matrix, color) {
    const points = [
      x1,
      y1 + width / 2,
      x1,
      y2 - width / 2,
      x2,
      y1 + width / 2,
      x1,
      y2 - width / 2,
      x2,
      y1 + width / 2,
      x2,
      y2 - width / 2,
    ];
    _createBuffer(points);
    _gl.useProgram(_lineShaderProgram);
    _gl.enableVertexAttribArray(_linePositionAttributeLocation);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _linePositionAttributeLocation,
      2,
      _gl.FLOAT,
      false,
      0,
      0
    );

    // 设置颜色
    _gl.uniform4f(_lineFragColor, color.r, color.g, color.b, 1);

    // 设置变换矩阵
    _gl.uniformMatrix3fv(_linematrixLocation, false, matrix);

    _gl.drawArrays(_gl.TRIANGLES, 0, points.length / 2);
  }

  /**
   * 绘制沿y轴方向的有宽度的直线
   * @param {*} x1
   * @param {*} y1
   * @param {*} x2
   * @param {*} y2
   * @param {*} width
   * @param {*} matrix
   * @param {*} color
   */
  function _drawYLineWithWidth(x1, y1, x2, y2, width, matrix, color) {
    const points = [
      x1 + width / 2,
      y1,
      x1 + width / 2,
      y2,
      x2 - width / 2,
      y1,
      x1 + width / 2,
      y2,
      x2 - width / 2,
      y1,
      x2 - width / 2,
      y2,
    ];
    _createBuffer(points);
    _gl.useProgram(_lineShaderProgram);
    _gl.enableVertexAttribArray(_linePositionAttributeLocation);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _linePositionAttributeLocation,
      2,
      _gl.FLOAT,
      false,
      0,
      0
    );

    // 设置颜色
    _gl.uniform4f(_lineFragColor, color.r, color.g, color.b, 1);

    // 设置变换矩阵
    _gl.uniformMatrix3fv(_linematrixLocation, false, matrix);

    _gl.drawArrays(_gl.TRIANGLES, 0, points.length / 2);
  }
  /**
   * 绘制透明矩形
   * @param {*} points 矩形6个点的坐标
   * @param {*} matrix
   * @param {*} color
   */
  function _drawTransparentRect(points, matrix, color) {
    _createBuffer(points);
    _gl.enable(_gl.BLEND);
    // 指定混合函数
    _gl.blendFunc(_gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA);
    _gl.useProgram(_lineShaderProgram);
    _gl.enableVertexAttribArray(_linePositionAttributeLocation);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _linePositionAttributeLocation,
      2,
      _gl.FLOAT,
      false,
      0,
      0
    );

    // 设置颜色
    _gl.uniform4f(_lineFragColor, color.r, color.g, color.b, 0.35);

    // 设置变换矩阵
    _gl.uniformMatrix3fv(_linematrixLocation, false, matrix);

    _gl.drawArrays(_gl.TRIANGLES, 0, points.length / 2);
  }

  /**
   * 绘制矩形 每个点单独设置颜色
   * @param {*} points 矩形点数组
   * @param {*} matrix 变换矩阵
   * @param {*} colors 颜色数组(vec4)
   */
  function _drawTranglesWithVaringColor(points, matrix, colors) {
    _createBuffer(points);
    _gl.enable(_gl.BLEND);
    // 指定混合函数
    _gl.blendFunc(_gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA);
    _gl.useProgram(_lineShaderProgramUseVaringColor);
    _gl.enableVertexAttribArray(_linePositionAttributeLocationUseVaringColor);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _linePositionAttributeLocationUseVaringColor,
      2,
      _gl.FLOAT,
      false,
      0,
      0
    );

    // 设置颜色
    _createBuffer2(colors);
    _gl.enableVertexAttribArray(_lineColorAttributeLocationUseVaringColor);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _lineColorAttributeLocationUseVaringColor,
      4,
      _gl.FLOAT,
      false,
      0,
      0
    );

    // 设置变换矩阵
    _gl.uniformMatrix3fv(_linematrixLocationUseVaringColor, false, matrix);

    _gl.drawArrays(_gl.TRIANGLES, 0, points.length / 2);
  }

  /**
   * 绘制透明图形
   * @param {*} points 点的坐标
   * @param {*} matrix
   * @param {*} color
   */
  function _drawTransparentTrangleFan(points, matrix, color) {
    _createBuffer(points);
    _gl.enable(_gl.BLEND);
    // 指定混合函数
    _gl.blendFunc(_gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA);
    _gl.useProgram(_lineShaderProgram);
    _gl.enableVertexAttribArray(_linePositionAttributeLocation);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _linePositionAttributeLocation,
      2,
      _gl.FLOAT,
      false,
      0,
      0
    );

    if (color.a) {
      // 设置颜色
      _gl.uniform4f(_lineFragColor, color.r, color.g, color.b, color.a);
    } else {
      // 设置颜色
      _gl.uniform4f(_lineFragColor, color.r, color.g, color.b, 0.2);
    }

    // 设置变换矩阵
    _gl.uniformMatrix3fv(_linematrixLocation, false, matrix);

    _gl.drawArrays(_gl.TRIANGLE_FAN, 0, points.length / 2);
  }

  /**
   * 绘制三角形
   * @param {*} points 三角形点的坐标
   * @param {*} matrix
   * @param {*} color
   */
  function _drawTrangles(points, matrix, color) {
    _createBuffer(points);
    _gl.useProgram(_lineShaderProgram);
    _gl.enableVertexAttribArray(_linePositionAttributeLocation);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _linePositionAttributeLocation,
      2,
      _gl.FLOAT,
      false,
      0,
      0
    );

    // 设置颜色
    _gl.uniform4f(_lineFragColor, color.r, color.g, color.b, 1);

    // 设置变换矩阵
    _gl.uniformMatrix3fv(_linematrixLocation, false, matrix);

    _gl.drawArrays(_gl.TRIANGLES, 0, points.length / 2);
  }

  /**
   * 绘制透明的三角形
   * @param {*} points 三角形点的坐标
   * @param {*} matrix
   * @param {*} color
   */
  function _drawTransparentTrangles(points, matrix, color) {
    _createBuffer(points);
    _gl.enable(_gl.BLEND);
    // 指定混合函数
    _gl.blendFunc(_gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA);
    _gl.useProgram(_lineShaderProgram);
    _gl.enableVertexAttribArray(_linePositionAttributeLocation);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _linePositionAttributeLocation,
      2,
      _gl.FLOAT,
      false,
      0,
      0
    );

    // 设置颜色
    _gl.uniform4f(_lineFragColor, color.r, color.g, color.b, color.a);

    // 设置变换矩阵
    _gl.uniformMatrix3fv(_linematrixLocation, false, matrix);

    _gl.drawArrays(_gl.TRIANGLES, 0, points.length / 2);
  }

  /**
   * 绘制圆圈
   * @param {*} vertexData 圆圈上的点
   */
  function _drawHollowCircleWithPoints(points, matrix, color) {
    _createBuffer(points);
    _gl.useProgram(_lineShaderProgram);
    _gl.enableVertexAttribArray(_linePositionAttributeLocation);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _linePositionAttributeLocation,
      2,
      _gl.FLOAT,
      false,
      0,
      0
    );

    // 设置颜色
    _gl.uniform4f(_lineFragColor, color.r, color.g, color.b, 1);

    // 设置变换矩阵
    _gl.uniformMatrix3fv(_linematrixLocation, false, matrix);

    _gl.drawArrays(_gl.LINE_LOOP, 0, points.length / 2);
  }

  /**
   * 绘制多个有宽度的点
   */
  function _drawWidthPoints(points, matrix, size, color) {
    // 准备输入数据
    _createBuffer(points);
    const sizeData = size;
    // 加载着色器，准备读取缓冲区的数据
    _gl.useProgram(_pointShaderProgram);
    _gl.enableVertexAttribArray(_pointPositionAttributeLocation);
    // gl.vertexAttribPointer(position_attribute_location, size, type, normalize, stride, offset);
    // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
    // type=gl_FLOAT表示使用的是32为浮点类型的数据。
    // normalize=false表示不需要归一化数据。
    // offset=0表示从缓冲区的开始位置读取数据。
    _gl.vertexAttribPointer(
      _pointPositionAttributeLocation,
      2,
      _gl.FLOAT,
      false,
      0,
      0
    );

    _gl.uniform4f(_pointFragColor, color.r, color.g, color.b, 1);

    _createBuffer(sizeData);
    _gl.vertexAttribPointer(
      _pointSizeAttributeLocation,
      1,
      _gl.FLOAT,
      false,
      0,
      0
    );
    _gl.enableVertexAttribArray(_pointSizeAttributeLocation);

    // 设置变换矩阵
    _gl.uniformMatrix3fv(_pointMatrixLocation, false, matrix);

    _gl.drawArrays(_gl.POINTS, 0, points.length / 2);
  }

  // --------------------------------------------------------------------
  // 顶点着色器和片原着色器代码

  // 绘制点的顶点着色器代码
  const pointVertexShaderSource = `
    attribute vec2 a_position;
    attribute float a_PointSize;
    uniform mat3 matrix;
    void main() {
        gl_PointSize= a_PointSize;
        gl_Position = vec4(matrix  * vec3(a_position, 1), 1);
    }
  `;
  // 绘制点的片原着色器代码
  const pointFragmentShaderSource = `
      precision mediump float;
      uniform vec4 u_FragColor;
      void main() {
          float d = distance(gl_PointCoord,vec2(0.5,0.5));
          if(d < 0.5){
            gl_FragColor = u_FragColor;
          }else{
              discard;
          }
      }
  `;

  // 绘制线的顶点着色器代码
  const lineVertexShaderSource = `
    attribute vec2 a_position;
    uniform mat3 matrix;
    void main() {
        gl_PointSize=100.0;
        gl_Position = vec4((matrix  * vec3(a_position, 1)).xy, 0, 1);
    }
  `;
  // 绘制线的片原着色器代码
  const lineFragmentShaderSource = `
      precision mediump float;
      uniform vec4 u_FragColor;
      void main() {
        gl_FragColor = u_FragColor;
      }
  `;
  // 绘制线的顶点着色器代码(每个点的颜色单独传入 费内存)
  const lineVertexShaderSourceUseVaringColor = `
    attribute vec2 a_position;
    attribute vec4 a_color;
    uniform mat3 matrix;
    varying vec4 v_color;
    void main() {
        gl_PointSize=100.0;
        gl_Position = vec4((matrix  * vec3(a_position, 1)).xy, 0, 1);
        v_color = a_color;
    }
  `;
  // 绘制线的片原着色器代码()
  const lineFragmentShaderSourceUseVaringColor = `
      precision mediump float;
      varying vec4 v_color;
      void main() {
        gl_FragColor = v_color;
      }
  `;

  // 绘制图像的顶点着色器代码
  const imgVertexShaderSource = `
    attribute vec2 a_position;
    attribute vec2 a_texCoord;

    uniform mat3 u_matrix;
    
    varying vec2 v_texCoord;
    
    void main() {
      gl_Position = vec4(u_matrix * vec3(a_position,1), 1);
    
      // pass the texCoord to the fragment shader
      // The GPU will interpolate this value between points.
      v_texCoord = a_texCoord;
    }
  `;
  const imgFragmentShaderSource = `
    precision mediump float;

    // our texture
    uniform sampler2D u_image;

    // the texCoords passed in from the vertex shader.
    varying vec2 v_texCoord;

    void main() {
      gl_FragColor = texture2D(u_image, v_texCoord);
    }
  `;
  // -------------------------------------------------------------------------------
  /**
   * 全部涂黑
   */
  function _clear() {
    _gl.clearColor(
      _config.background.r,
      _config.background.g,
      _config.background.b,
      1
    );
    _gl.clear(_gl.COLOR_BUFFER_BIT);
    // 清空二维画布
    _textCtx.clearRect(0, 0, _container.clientWidth, _container.clientHeight);
  }
  /**
   * 刷新当前图表
   */
  function _refresh() {
    // 检测图表大小是否改变
    if (
      containerHeight != _container.clientHeight ||
      containerWidth != _container.clientWidth
    ) {
      const div = _config.container;
      _container.width = div.clientWidth;
      _container.height = div.clientHeight;
      _textcontainer.width = div.clientWidth;
      _textcontainer.height = div.clientHeight;
      _textCtx.width = div.clientWidth;
      _textCtx.height = div.clientHeight;
      containerWidth = div.clientWidth;
      containerHeight = div.clientHeight;
      _clearCaculatedData();
      // 清空计算矩阵
      _axisMatrix = null;
      _Series.forEach((series) => {
        series._linesMatrix = null;
        // 清空axis标记  的文字缓存
        series.xAxis.points = [];
        series.yAxis.points = [];
      });
    }
    // 清空所有区域
    _clear();
    if (_config.type === "compass") {
      _drawCompassCircle();
      _drawCarPosition();
      _drawCompassPointer();
      _drawCompassPoints();
      _drawMouseStrap();
    } else {
      // 在axis区域填充颜色
      _fillAxisArea();
      // 绘制图表x轴y轴
      _drawSeriesAxis();
      if (_config.type === "pubu") {
        _drawImage2D();
        _drawRectMarkZone();
      }
      _drawSeriesMouseStrapRect();
      _drawSeriesMouseStrapMeasureRect();
      _drawXMarkZones();
      _drawMarkLines();
      _drawMouseClickMarkPoints();
      if (_config.type === "line") {
        // 绘制线条
        _drawSeriesLine();
        // 绘制中心竖直虚线
        _config.drawCenterLine && _drawCenterDashLine();
      }
      if (_config.type === "line") {
        _drawMeasure();
      }
      if (_config.type === "pubu") {
        _drawTimeMeasure();
        _drawWaterColors();
      }
    }
  }
  /**
   * 绘制中心竖直虚线
   */
  function _drawCenterDashLine() {
    _Series.forEach((series, index) => {
      // 设置使用的着色器和viewport
      _gl.useProgram(_lineShaderProgram);
      _gl.viewport(0, 0, _gl.canvas.width, _gl.canvas.height);

      if (
        !series.centerDashLinePoints ||
        series.centerDashLinePoints.length == 0
      ) {
        const x =
          series.yAxis.padding +
          (_container.clientWidth -
            series.yAxis.padding -
            series.yAxis.defaltPadding) /
            2;

        const length = 5;
        const interval = 2;
        const startY = series.xAxis.padding;
        const endY = _container.clientHeight - series.xAxis.defaltPadding;
        const data = [];
        let tmp = startY;
        while (tmp < endY) {
          data.push(x);
          data.push(tmp);
          data.push(x);
          data.push(tmp + length);
          tmp += length + interval;
        }
        series.centerDashLinePoints = data;
      }

      _drawLineGroup(series.centerDashLinePoints, _axisMatrix, {
        r: 255 / 255,
        g: 0 / 255,
        b: 0 / 255,
      });
    });
  }

  /**
   * 绘制罗盘图的圆圈
   */
  function _drawCompassCircle() {
    if (!_compassConfig.compassMatrix) {
      // 根据分辨率直接生成矩阵
      let projectionMatrix = m3.projection(
        _gl.canvas.clientWidth,
        _gl.canvas.clientHeight
      );
      // 因为上面的方法生成的矩阵原点在左上方 需要原点在左下方,所以先沿y轴平移canvas高度(向上),在沿y轴翻转 (这样原点的坐标就在左下了)
      const translationMatrix = m3.translation(0, _gl.canvas.clientHeight);
      projectionMatrix = m3.multiply(projectionMatrix, translationMatrix);
      // scaling 绕原点翻转(-1 ~ 1)
      projectionMatrix = m3.multiply(projectionMatrix, m3.scaling(1, -1));
      projectionMatrix = m3.multiply(
        projectionMatrix,
        m3.translation(_gl.canvas.clientWidth / 2, _gl.canvas.clientHeight / 2)
      );
      // _axisMatrix = projectionMatrix
      if (_compassConfig.compassScaleRotation) {
        projectionMatrix = m3.multiply(
          projectionMatrix,
          m3.rotation(_compassConfig.compassScaleRotation)
        );
      }
      _compassConfig.compassMatrix = projectionMatrix;
    }

    const banjing = _container.clientHeight / 2 - 5;
    const N = 4000;
    const circlePoints = [];
    // var sizeData = [pointSize, pointSize]

    // for (var i = 0; i <= N; i++) {
    //   let theta = i * 2 * Math.PI / N
    //   let x1 = 0 + banjing * Math.sin(theta)
    //   let y1 = 0 + banjing * Math.cos(theta)
    //   circlePoints.push(x1, y1)
    //   // sizeData.push(pointSize)
    // }
    // _drawHollowCircleWithPoints(circlePoints, _compassConfig.compassMatrix, {r: 1, g: 1, b: 1})

    //
    const circlePoints2 = [];
    for (let j = 0; j <= 60; j++) {
      const theta = (j * 2 * Math.PI) / 60;
      const x1 = 0 + banjing * Math.sin(theta);
      const y1 = 0 + banjing * Math.cos(theta);
      const x2 = 0 + (banjing - 5) * Math.sin(theta);
      const y2 = 0 + (banjing - 5) * Math.cos(theta);
      circlePoints2.push(x1);
      circlePoints2.push(y1);
      circlePoints2.push(x2);
      circlePoints2.push(y2);
    }
    _drawLineGroup(
      circlePoints2,
      _compassConfig.compassMatrix,
      _compassConfig.wordColor
    );

    // 绘制罗盘上的文字
    // 绘制中心的方位和置信度
    _textCtx.fillStyle =
      "rgb(" +
      _compassConfig.wordColor.r * 255 +
      "," +
      _compassConfig.wordColor.g * 255 +
      "," +
      _compassConfig.wordColor.b * 255 +
      ")";
    _textCtx.font = "20px sans-serif";
    if (_compassConfig.compassPointRotation != null) {
      const direction = (
        (_compassConfig.compassPointRotation * 180) /
        Math.PI
      ).toFixed(3);
      const str = direction + "°";
      _textCtx.fillText(
        str,
        _container.clientWidth / 2 - _textCtx.measureText(str).width - 5,
        _container.clientHeight / 2
      );
    }
    if (_compassConfig.confidence != null) {
      const str = _compassConfig.confidence;
      _textCtx.fillText(
        str,
        _container.clientWidth / 2 + 5,
        _container.clientHeight / 2
      );
    }

    for (let i = 0; i < 12; i++) {
      let rotation = i * 30 * ((2 * Math.PI) / 360);
      if (_compassConfig.compassScaleRotation) {
        rotation += _compassConfig.compassScaleRotation;
      }
      let str = i * 30 + "";
      if (i === 0) {
        str = "N";
      }
      if (i === 3) {
        str = "E";
      }
      if (i === 6) {
        str = "S";
      }
      if (i === 9) {
        str = "W";
      }
      const banjing = _container.clientWidth / 2 - 20;
      const x =
        Math.sin(rotation) * banjing +
        _container.clientHeight / 2 -
        _textCtx.measureText(str).width / 2;
      const y =
        _container.clientHeight -
        (Math.cos(rotation) * banjing + _container.clientHeight / 2) +
        5;

      _textCtx.font = "10px sans-serif";
      _textCtx.fillText(str, x, y);

      // 绘制罗盘外层彩色圈圈
      const colorsTmp = waterColor.dirColors();
      const colors = [];
      for (let i = 0; i < colorsTmp.length; i++) {
        colors.push(colorsTmp[colorsTmp.length - 1 - i]);
      }
      const num = 240;
      const colorBanjing1 = _container.clientHeight / 2 - 5;
      const colorBanjing2 = _container.clientHeight / 2;
      const colorCirclePoints = [];
      const colorCirclePointsColors = [];
      let preX1;
      let preY1;
      let preX2;
      let preY2;
      for (let i = 0; i <= num; i++) {
        const theta = (i * 2 * Math.PI) / num;
        // 内层点坐标
        const x1 = 0 + colorBanjing1 * Math.sin(theta);
        const y1 = 0 + colorBanjing1 * Math.cos(theta);
        // 外层点坐标
        const x2 = 0 + colorBanjing2 * Math.sin(theta);
        const y2 = 0 + colorBanjing2 * Math.cos(theta);
        if (i > 0) {
          colorCirclePoints.push(preX1);
          colorCirclePoints.push(preY1);
          colorCirclePoints.push(preX2);
          colorCirclePoints.push(preY2);
          colorCirclePoints.push(x1);
          colorCirclePoints.push(y1);
          colorCirclePoints.push(preX2);
          colorCirclePoints.push(preY2);
          colorCirclePoints.push(x1);
          colorCirclePoints.push(y1);
          colorCirclePoints.push(x2);
          colorCirclePoints.push(y2);
          const precolor = colors[i - 1];
          const color = i < colors.length ? colors[i] : precolor;
          colorCirclePointsColors.push(precolor.R / 255);
          colorCirclePointsColors.push(precolor.G / 255);
          colorCirclePointsColors.push(precolor.B / 255);
          colorCirclePointsColors.push(1.0);
          colorCirclePointsColors.push(precolor.R / 255);
          colorCirclePointsColors.push(precolor.G / 255);
          colorCirclePointsColors.push(precolor.B / 255);
          colorCirclePointsColors.push(1.0);
          colorCirclePointsColors.push(color.R / 255);
          colorCirclePointsColors.push(color.G / 255);
          colorCirclePointsColors.push(color.B / 255);
          colorCirclePointsColors.push(1.0);
          colorCirclePointsColors.push(precolor.R / 255);
          colorCirclePointsColors.push(precolor.G / 255);
          colorCirclePointsColors.push(precolor.B / 255);
          colorCirclePointsColors.push(1.0);
          colorCirclePointsColors.push(color.R / 255);
          colorCirclePointsColors.push(color.G / 255);
          colorCirclePointsColors.push(color.B / 255);
          colorCirclePointsColors.push(1.0);
          colorCirclePointsColors.push(color.R / 255);
          colorCirclePointsColors.push(color.G / 255);
          colorCirclePointsColors.push(color.B / 255);
          colorCirclePointsColors.push(1.0);
        }
        preX1 = x1;
        preY1 = y1;
        preX2 = x2;
        preY2 = y2;
      }
      _drawTranglesWithVaringColor(
        colorCirclePoints,
        _compassConfig.compassMatrix,
        colorCirclePointsColors
      );
    }
  }

  /**
   * 绘制车位
   */
  function _drawCarPosition() {
    if (_compassConfig.compassCarPositionRotation == null) {
      // _compassConfig.compassCarPositionRotation = 0
      return;
    }
    if (!_compassConfig.compassCarPositionMatrix) {
      // 根据分辨率直接生成矩阵
      let projectionMatrix = m3.projection(
        _gl.canvas.clientWidth,
        _gl.canvas.clientHeight
      );
      // 因为上面的方法生成的矩阵原点在左上方 需要原点在左下方,所以先沿y轴平移canvas高度(向上),在沿y轴翻转 (这样原点的坐标就在左下了)
      const translationMatrix = m3.translation(0, _gl.canvas.clientHeight);
      projectionMatrix = m3.multiply(projectionMatrix, translationMatrix);
      // scaling 绕原点翻转(-1 ~ 1)
      projectionMatrix = m3.multiply(projectionMatrix, m3.scaling(1, -1));
      projectionMatrix = m3.multiply(
        projectionMatrix,
        m3.translation(_gl.canvas.clientWidth / 2, _gl.canvas.clientHeight / 2)
      );
      // _axisMatrix = projectionMatrix
      projectionMatrix = m3.multiply(
        projectionMatrix,
        m3.rotation(_compassConfig.compassCarPositionRotation)
      );
      _compassConfig.compassCarPositionMatrix = projectionMatrix;
    }
    const banjing = _container.clientHeight / 2 - 5;
    const points = [
      0,
      banjing - 20,
      8,
      banjing - 45,
      -8,
      banjing - 45,
      8,
      banjing - 45,
      -8,
      banjing - 45,
      -8,
      -banjing + 20,
      8,
      banjing - 45,
      -8,
      -banjing + 20,
      8,
      -banjing + 20,
    ];
    _drawTransparentTrangles(points, _compassConfig.compassCarPositionMatrix, {
      r: 1,
      g: 1,
      b: 1,
      a: 0.4,
    });
    // _drawTrangles(points, _compassConfig.compassCarPositionMatrix, {r: 1, g: 1, b: 1})
  }

  /**
   * 绘制罗盘上的点
   */
  function _drawCompassPoints() {
    if (_compassConfig.comapssShowPoints.length === 0) {
      _compassConfig.comapssShowPointsColors = [];
      // 计算哪些点需要被展示
      _compassConfig.comapssPoints.forEach((item) => {
        const currentRotation = 2 * Math.PI * (item.angle / 360);
        if (
          Math.abs(_compassConfig.pointShowJiaoDuChange) < 2 * Math.PI &&
          _compassConfig.pointShowJiaoDuChange != null &&
          _compassConfig.pointShowJiaoDuChange != 0
        ) {
          if (_compassConfig.pointShowJiaoDuChange < 0) {
            // 逆时针
            if (_compassConfig.startRotation > _compassConfig.stopRotation) {
              // 没有越过y轴
              if (
                currentRotation > _compassConfig.stopRotation &&
                currentRotation < _compassConfig.startRotation
              ) {
                const drawPoints = _transfromCompassPointsToRect(
                  item.xToRect,
                  item.yToRect,
                  currentRotation
                );
                _compassConfig.comapssShowPoints =
                  _compassConfig.comapssShowPoints.concat(drawPoints);
                _compassConfig.compassShowPointSizes.push(
                  _compassConfig.pointSize
                );
              }
            } else {
              // 越过y轴
              if (
                currentRotation > _compassConfig.stopRotation ||
                currentRotation < _compassConfig.startRotation
              ) {
                const drawPoints = _transfromCompassPointsToRect(
                  item.xToRect,
                  item.yToRect,
                  currentRotation
                );
                _compassConfig.comapssShowPoints =
                  _compassConfig.comapssShowPoints.concat(drawPoints);
                _compassConfig.compassShowPointSizes.push(
                  _compassConfig.pointSize
                );
              }
            }
          } else {
            // 顺时针
            if (_compassConfig.stopRotation > _compassConfig.startRotation) {
              // 没有越过y轴
              if (
                currentRotation > _compassConfig.startRotation &&
                currentRotation < _compassConfig.stopRotation
              ) {
                const drawPoints = _transfromCompassPointsToRect(
                  item.xToRect,
                  item.yToRect,
                  currentRotation
                );
                _compassConfig.comapssShowPoints =
                  _compassConfig.comapssShowPoints.concat(drawPoints);
                _compassConfig.compassShowPointSizes.push(
                  _compassConfig.pointSize
                );
              }
            } else {
              if (
                currentRotation > _compassConfig.startRotation ||
                currentRotation < _compassConfig.stopRotation
              ) {
                const drawPoints = _transfromCompassPointsToRect(
                  item.xToRect,
                  item.yToRect,
                  currentRotation
                );
                _compassConfig.comapssShowPoints =
                  _compassConfig.comapssShowPoints.concat(drawPoints);
                _compassConfig.compassShowPointSizes.push(
                  _compassConfig.pointSize
                );
              }
            }
          }
        } else {
          const drawPoints = _transfromCompassPointsToRect(
            item.xToRect,
            item.yToRect,
            currentRotation
          );
          _compassConfig.comapssShowPoints =
            _compassConfig.comapssShowPoints.concat(drawPoints);
          _compassConfig.compassShowPointSizes.push(_compassConfig.pointSize);
        }
        _compassConfig.comapssShowPointsColors =
          _compassConfig.comapssShowPointsColors.concat([
            item.color.r,
            item.color.g,
            item.color.b,
            1,
            item.color.r,
            item.color.g,
            item.color.b,
            1,
            item.color.r,
            item.color.g,
            item.color.b,
            1,
            item.color.r,
            item.color.g,
            item.color.b,
            1,
            item.color.r,
            item.color.g,
            item.color.b,
            1,
            item.color.r,
            item.color.g,
            item.color.b,
            1,
          ]);
      });
    }
    _drawTranglesWithVaringColor(
      _compassConfig.comapssShowPoints,
      _compassConfig.compassMatrix,
      _compassConfig.comapssShowPointsColors
    );
    // _drawTrangles(_compassConfig.comapssShowPoints, _compassConfig.compassMatrix, {r: 0, g: 1, b: 1})
    // _drawWidthPoints(_compassConfig.comapssShowPoints, _compassConfig.compassMatrix, _compassConfig.compassShowPointSizes, {r: 0, g: 1, b: 1})
    // _drawLineGroup(_compassConfig.comapssShowPoints, _compassConfig.compassMatrix,{r: 0, g: 1, b: 1})
  }

  /**
   * 将罗盘图上的点转换成需要绘制的有宽度的线的坐标
   */
  function _transfromCompassPointsToRect(x, y, rotation) {
    let matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];
    matrix = m3.rotation(rotation, matrix);
    const banjing = _container.clientHeight / 2 - 10;
    const width = 2;
    const points = [
      [x - width / 2, banjing],
      [x + width / 2, banjing],
      [x - width / 2, banjing - y],
      [x - width / 2, banjing - y],
      [x + width / 2, banjing - y],
      [x + width / 2, banjing],
    ];
    let tansfromedPoints = [];
    points.forEach((point) => {
      tansfromedPoints = tansfromedPoints.concat(
        m3.transformPoint(matrix, point)
      );
    });
    // //console.log(tansfromedPoints)
    return tansfromedPoints;
  }

  /**
   * 绘制罗盘指针
   */
  function _drawCompassPointer() {
    if (_compassConfig.compassPointRotation == null) {
      return;
    }
    // 根据分辨率直接生成矩阵
    let projectionMatrix = m3.projection(
      _gl.canvas.clientWidth,
      _gl.canvas.clientHeight
    );
    // 因为上面的方法生成的矩阵原点在左上方 需要原点在左下方,所以先沿y轴平移canvas高度(向上),在沿y轴翻转 (这样原点的坐标就在左下了)
    const translationMatrix = m3.translation(0, _gl.canvas.clientHeight);
    projectionMatrix = m3.multiply(projectionMatrix, translationMatrix);
    // scaling 绕原点翻转(-1 ~ 1)
    projectionMatrix = m3.multiply(projectionMatrix, m3.scaling(1, -1));
    projectionMatrix = m3.multiply(
      projectionMatrix,
      m3.translation(_gl.canvas.clientWidth / 2, _gl.canvas.clientHeight / 2)
    );
    // _axisMatrix = projectionMatrix
    projectionMatrix = m3.multiply(
      projectionMatrix,
      m3.rotation(_compassConfig.compassPointRotation)
    );

    if (_compassConfig.compassScaleRotation) {
      projectionMatrix = m3.multiply(
        projectionMatrix,
        m3.rotation(_compassConfig.compassScaleRotation)
      );
    }
    _compassConfig.compassPointMatrix = projectionMatrix;

    const width = 3;
    const points = [
      width,
      _container.clientHeight / 2 - 5,
      width,
      0,
      -width,
      0,
      -width,
      0,
      -width,
      _container.clientHeight / 2 - 5,
      width,
      _container.clientHeight / 2 - 5,
    ];
    _drawTrangles(points, _compassConfig.compassPointMatrix, {
      r: 1,
      g: 0,
      b: 0,
    });
    // _drawLineGroupWithLineStrip(points, _compassPointMatrix, {r: 1, g: 1, b: 1})
  }

  /**
   * 绘制鼠标拖动区域的扇形
   */
  function _drawMouseStrap() {
    if (_compassConfig.sectorPoints && _compassConfig.sectorPoints.length > 0) {
      _drawTransparentTrangleFan(
        _compassConfig.sectorPoints,
        _compassConfig.compassMatrix,
        { r: 1, g: 1, b: 1 }
      );
    }
  }

  /**
   * 填充axis内部颜色为黑色
   */
  function _fillAxisArea() {
    // 设置使用的着色器和viewport
    _gl.useProgram(_lineShaderProgram);
    _gl.viewport(0, 0, _gl.canvas.width, _gl.canvas.height);
    // 循环绘制series
    _Series.forEach((series, index) => {
      if (!_axisMatrix) {
        // 计算矩阵
        // 根据分辨率直接生成矩阵
        let projectionMatrix = m3.projection(
          _gl.canvas.clientWidth,
          _gl.canvas.clientHeight
        );
        // 因为上面的方法生成的矩阵原点在左上方 需要原点在左下方,所以先沿y轴平移canvas高度(向上),在沿y轴翻转 (这样原点的坐标就在左下了)
        const translationMatrix = m3.translation(0, _gl.canvas.clientHeight);
        projectionMatrix = m3.multiply(projectionMatrix, translationMatrix);
        // scaling 绕原点翻转(-1 ~ 1)
        projectionMatrix = m3.multiply(projectionMatrix, m3.scaling(1, -1));
        _axisMatrix = projectionMatrix;
      }
      // 设置使用的着色器和viewport
      _gl.useProgram(_lineShaderProgram);
      _gl.viewport(0, 0, _gl.canvas.width, _gl.canvas.height);
      const points = [
        series.yAxis.padding,
        series.xAxis.padding,
        series.yAxis.padding,
        _container.clientHeight - series.xAxis.defaltPadding,
        _container.clientWidth - series.yAxis.defaltPadding,
        _container.clientHeight - series.xAxis.defaltPadding,
        _container.clientWidth - series.yAxis.defaltPadding,
        _container.clientHeight - series.xAxis.defaltPadding,
        _container.clientWidth - series.yAxis.defaltPadding,
        series.xAxis.padding,
        series.yAxis.padding,
        series.xAxis.padding,
      ];
      _drawTrangles(points, _axisMatrix, { r: 0, g: 0, b: 0 });
    });
  }

  /**
   * 绘制xaxis和yaxis
   */
  function _drawSeriesAxis() {
    // 设置使用的着色器和viewport
    _gl.useProgram(_lineShaderProgram);
    _gl.viewport(0, 0, _gl.canvas.width, _gl.canvas.height);
    if (!_axisMatrix) {
      // 计算矩阵
      // 根据分辨率直接生成矩阵
      let projectionMatrix = m3.projection(
        _gl.canvas.clientWidth,
        _gl.canvas.clientHeight
      );
      // 因为上面的方法生成的矩阵原点在左上方 需要原点在左下方,所以先沿y轴平移canvas高度(向上),在沿y轴翻转 (这样原点的坐标就在左下了)
      const translationMatrix = m3.translation(0, _gl.canvas.clientHeight);
      projectionMatrix = m3.multiply(projectionMatrix, translationMatrix);
      // scaling 绕原点翻转(-1 ~ 1)
      projectionMatrix = m3.multiply(projectionMatrix, m3.scaling(1, -1));
      _axisMatrix = projectionMatrix;
    }

    // 循环绘制series
    _Series.forEach((item, index) => {
      // 绘制X轴单位
      if (item.axisXUnits && item.axisXUnits.text) {
        _textCtx.font = "12px sans-serif";
        _textCtx.fillStyle = "rgb(25,190,5)";
        const axisXUnitsX =
          item.axisXUnits.left -
          _textCtx.measureText(item.axisXUnits.text).width / 2;
        const axisXUnitsY = item.axisXUnits.top - 8;
        _textCtx.fillText(item.axisXUnits.text, axisXUnitsX, axisXUnitsY);
      }

      // 绘制Y轴单位
      if (item.axisYUnits && item.axisYUnits.text) {
        _textCtx.font = "12px sans-serif";
        _textCtx.fillStyle = "rgb(25,190,5)";
        const axisXUnitsX = item.axisYUnits.left;
        let axisXUnitsY =
          item.axisYUnits.top -
          _textCtx.measureText(item.axisYUnits.text).width / 2;
        // let content = item.axisYUnits.text.split('').reverse().join(',') // 反转数组
        const content = item.axisYUnits.text;
        for (let i = 0; i < content.length; i++) {
          const str = content.slice(i, i + 1).toString();
          if (str.match(/[A-Za-z0-9]/)) {
            // 非汉字 旋转
            _textCtx.save();
            _textCtx.translate(axisXUnitsX, axisXUnitsY);
            _textCtx.rotate((90 * Math.PI) / 180); // 逆时针转90度
            _textCtx.textBaseline = "bottom";
            _textCtx.fillText(str, 0, 0);
            _textCtx.restore();
            axisXUnitsY += _textCtx.measureText(str).width; // 计算文字宽度
          } else if (str.match(/[\u4E00-\u9FA5]/)) {
            _textCtx.save();
            _textCtx.textBaseline = "top";
            _textCtx.fillText(str, axisXUnitsX, axisXUnitsY);
            _textCtx.restore();
            axisXUnitsY += _textCtx.measureText(str).width; // 计算文字宽度
          }
        }
      }

      // 绘制右上角提示信息
      if (
        item.tooltip &&
        item.tooltip.value1 !== "" &&
        item.tooltip.value2 !== ""
      ) {
        _textCtx.font = "12px sans-serif";
        _textCtx.fillStyle = "#9fb7b7";
        if (
          item.tooltip.value1 !== undefined &&
          item.tooltip.value2 !== undefined
        ) {
          const str1 =
            item.tooltip.value1 === null
              ? ""
              : `频率: ${Number(item.tooltip.value1).toFixed(3)}MHz`;
          const str2 =
            item.tooltip.value2 === null
              ? ""
              : `强度: ${Number(item.tooltip.value2).toFixed(2)}dBm`;
          const str3 =
            item.tooltip.value3 === undefined
              ? ""
              : `增益: ${item.tooltip.value3}`;
          const str = `${str1} ${str2} ${str3}`;
          const axisXUnitsX =
            item.tooltip.left - _textCtx.measureText(str).width - 20;
          const axisXUnitsY = item.tooltip.top + 8;
          _textCtx.fillText(str, axisXUnitsX, axisXUnitsY);
        }
      }

      // 绘制标题文字
      if (item.title && item.title.text) {
        _textCtx.font = "bold 18px sans-serif";
        _textCtx.fillStyle = "#9fb7b7";
        const titleX =
          item.title.left - _textCtx.measureText(item.title.text).width / 2;
        const titleY = item.title.top + 10;
        _textCtx.fillText(item.title.text, titleX, titleY);
      }

      // 因为要计算文字长度 所以先设置文字字体和大小
      _textCtx.fillStyle =
        "rgb(" +
        item.yAxis.color.r * 255 +
        "," +
        item.yAxis.color.g * 255 +
        "," +
        item.yAxis.color.b * 255 +
        ")";
      _textCtx.font = "10px sans-serif";

      const realPaddingX = item.xAxis.padding;
      const realPaddingY = item.yAxis.padding;

      if (_config.type === "pubu" && item.direction === "rightToLeft") {
        // x轴和y轴对换
        if (item.yAxis.points.length === 0) {
          // 绘制网格线
          let tablePoints = [];
          // 先清空文字缓存
          item.yAxis.words = [];
          // 一条直线
          item.yAxis.points = item.yAxis.points.concat([
            realPaddingY,
            realPaddingX,
            realPaddingY,
            _gl.canvas.clientHeight - item.xAxis.defaltPadding,
          ]);

          const yAxisNum = item.xAxis.markNum;
          const yMarkInterval =
            (_container.clientHeight -
              item.xAxis.padding -
              item.xAxis.defaltPadding) /
            item.yAxis.markNum;
          const tmpYMarkStartY = realPaddingX;
          const startYvalue = item.xAxis.interval[0];
          const endYvalue = item.xAxis.interval[1];
          const yValueMarkInterval =
            (item.xAxis.interval[1] - item.xAxis.interval[0]) / yAxisNum;

          for (let j = 0; j <= yAxisNum; j++) {
            const tmpY = tmpYMarkStartY + j * yMarkInterval;
            // let tmpYvalue = (startYvalue + (j * yValueMarkInterval)).toFixed(2)
            const tmpYvalue = (endYvalue - j * yValueMarkInterval).toFixed(2);
            item.yAxis.points = item.yAxis.points.concat([
              realPaddingY,
              tmpY,
              realPaddingY - 5,
              tmpY,
            ]);
            if (_config.type === "line") {
              tablePoints = tablePoints.concat([
                realPaddingY,
                tmpY,
                _container.clientWidth - item.yAxis.defaltPadding,
                tmpY,
              ]);
            }
            let ystr = "";
            if (item.xAxis.xAxisMarkFormatter) {
              ystr = item.xAxis.xAxisMarkFormatter(tmpYvalue);
            } else {
              ystr = tmpYvalue.toString();
            }
            // item.yAxis.words.push({
            //   str: ystr,
            //   x: realPaddingY - (_textCtx.measureText(ystr).width) - 8,
            //   y: _container.height - tmpY + 4
            // })
            if (_config.type === "line") {
              item.yTablePoints = tablePoints;
            }
          }
        }
        if (item.xAxis.points.length === 0) {
          // 绘制网格线
          let tablePoints = [];
          // 先清空文字缓存
          item.xAxis.words = [];
          item.xAxis.points = item.xAxis.points.concat([
            realPaddingY,
            realPaddingX,
            _gl.canvas.clientWidth - item.yAxis.defaltPadding,
            realPaddingX,
          ]);
          // 直线上的多个节点
          const xAxisNum = item.yAxis.markNum;
          const xMarkInterval =
            (_container.clientWidth -
              item.yAxis.padding -
              item.yAxis.defaltPadding) /
            xAxisNum;
          const tmpXMarkStartX = realPaddingY;
          const startXvalue = item.yAxis.interval[0];
          const xValueMarkInterval =
            (item.yAxis.interval[1] - item.yAxis.interval[0]) / xAxisNum;

          for (let i = 0; i <= xAxisNum; i++) {
            const tmpX = tmpXMarkStartX + i * xMarkInterval;
            const tmpXvalue = (startXvalue + i * xValueMarkInterval).toFixed(2);
            item.xAxis.points = item.xAxis.points.concat([
              tmpX,
              realPaddingX,
              tmpX,
              realPaddingX - 5,
            ]);
            if (_config.type === "line") {
              tablePoints = tablePoints.concat([
                tmpX,
                realPaddingX,
                tmpX,
                _container.clientHeight - item.xAxis.defaltPadding,
              ]);
            }
            // ----------------------------------------
            // y轴x轴对调了！！！
            // ----------------------------------------
            let xstr = "";
            if (item.yAxis.yAxisMarkFormatter) {
              xstr = item.yAxis.yAxisMarkFormatter(tmpXvalue);
            } else {
              xstr = tmpXvalue.toString();
            }
            item.xAxis.words.push({
              str: xstr,
              x: tmpX - _textCtx.measureText(xstr).width / 2,
              // 减去了字体高度和 小标签的高度
              y: _container.height - (realPaddingX - 10 - 5),
            });
            if (_config.type === "line") {
              item.xTablePoints = tablePoints;
            }
            // //console.log(item.xAxis.points)
          }
        }
        if (_config.type === "line") {
          _drawLineGroup(item.xTablePoints, _axisMatrix, {
            r: 0,
            g: 80 / 255,
            b: 0,
          });
          _drawLineGroup(item.yTablePoints, _axisMatrix, {
            r: 0,
            g: 80 / 255,
            b: 0,
          });
        }
      } else {
        // 先计算xaxis yaxis各自的点的坐标
        if (item.yAxis.points.length === 0) {
          // 绘制网格线
          let tablePoints = [];
          // 先清空文字缓存
          item.yAxis.words = [];
          // 一条直线
          item.yAxis.points = item.yAxis.points.concat([
            realPaddingY,
            realPaddingX,
            realPaddingY,
            _gl.canvas.clientHeight - item.xAxis.defaltPadding,
          ]);

          const yMarkInterval =
            (_container.clientHeight -
              item.xAxis.padding -
              item.xAxis.defaltPadding) /
            item.yAxis.markNum;
          const tmpYMarkStartY = realPaddingX;
          const startYvalue = item.yAxis.interval[0];
          const yValueMarkInterval =
            (item.yAxis.interval[1] - item.yAxis.interval[0]) /
            item.yAxis.markNum;

          for (let j = 0; j <= item.yAxis.markNum; j++) {
            const tmpY = tmpYMarkStartY + j * yMarkInterval;
            const tmpYvalue = parseInt(startYvalue + j * yValueMarkInterval);

            item.yAxis.points = item.yAxis.points.concat([
              realPaddingY,
              tmpY,
              realPaddingY - 5,
              tmpY,
            ]);
            if (_config.type === "line") {
              tablePoints = tablePoints.concat([
                realPaddingY,
                tmpY,
                _container.clientWidth - item.yAxis.defaltPadding,
                tmpY,
              ]);
            }
            let ystr = "";
            if (item.yAxis.yAxisMarkFormatter) {
              ystr = item.yAxis.yAxisMarkFormatter(tmpYvalue);
            } else {
              ystr = tmpYvalue.toString();
            }
            if (item.yAxis.markNum != 1) {
              // 屏蔽窄带话音y轴数据
              item.yAxis.words.push({
                str: ystr,
                x: realPaddingY - _textCtx.measureText(ystr).width - 8,
                y: _container.height - tmpY + 4,
              });
            }

            if (_config.type === "line") {
              item.yTablePoints = tablePoints;
            }
          }
        }

        if (item.xAxis.points.length === 0) {
          // 绘制网格线
          let tablePoints = [];
          // 先清空文字缓存
          item.xAxis.words = [];
          item.xAxis.points = item.xAxis.points.concat([
            realPaddingY,
            realPaddingX,
            _gl.canvas.clientWidth - item.yAxis.defaltPadding,
            realPaddingX,
          ]);
          // 直线上的多个节点
          const xMarkInterval =
            (_container.clientWidth -
              item.yAxis.padding -
              item.yAxis.defaltPadding) /
            item.xAxis.markNum;
          const tmpXMarkStartX = realPaddingY;
          const startXvalue = item.xAxis.interval[0];
          const xValueMarkInterval =
            (item.xAxis.interval[1] - item.xAxis.interval[0]) /
            item.xAxis.markNum;

          let realMarkNum = item.xAxis.markNum;
          let realxValueMarkInterval = xValueMarkInterval;
          let realxMarkInterval = xMarkInterval;
          if (xValueMarkInterval < 5 * 1000000) {
          } else if (
            xValueMarkInterval > 5 * 1000000 &&
            xValueMarkInterval < 10 * 1000000
          ) {
            realxValueMarkInterval = 10 * 1000000;
          } else if (
            xValueMarkInterval > 10 * 1000000 &&
            xValueMarkInterval < 15 * 1000000
          ) {
            realxValueMarkInterval = 15 * 1000000;
          } else if (
            xValueMarkInterval > 15 * 1000000 &&
            xValueMarkInterval < 20 * 1000000
          ) {
            realxValueMarkInterval = 20 * 1000000;
          } else if (
            xValueMarkInterval > 25 * 1000000 &&
            xValueMarkInterval < 30 * 1000000
          ) {
            realxValueMarkInterval = 30 * 1000000;
          } else if (
            xValueMarkInterval > 30 * 1000000 &&
            xValueMarkInterval < 50 * 1000000
          ) {
            realxValueMarkInterval = 50 * 1000000;
          } else if (
            xValueMarkInterval > 30 * 1000000 &&
            xValueMarkInterval < 35 * 1000000
          ) {
            realxValueMarkInterval = 35 * 1000000;
          } else if (
            xValueMarkInterval > 35 * 1000000 &&
            xValueMarkInterval < 40 * 1000000
          ) {
            realxValueMarkInterval = 40 * 1000000;
          } else if (
            xValueMarkInterval > 40 * 1000000 &&
            xValueMarkInterval < 45 * 1000000
          ) {
            realxValueMarkInterval = 45 * 1000000;
          } else if (
            xValueMarkInterval > 45 * 1000000 &&
            xValueMarkInterval < 50 * 1000000
          ) {
            realxValueMarkInterval = 50 * 1000000;
          }
          realMarkNum = Math.floor(
            (item.xAxis.interval[1] - item.xAxis.interval[0]) /
              realxValueMarkInterval
          );
          realxMarkInterval =
            (realxValueMarkInterval /
              (item.xAxis.interval[1] - item.xAxis.interval[0])) *
            (_container.clientWidth -
              item.yAxis.padding -
              item.yAxis.defaltPadding);

          for (let i = 0; i <= realMarkNum; i++) {
            const tmpX = tmpXMarkStartX + i * realxMarkInterval;
            const tmpXvalue = (
              startXvalue +
              i * realxValueMarkInterval
            ).toFixed(2);
            item.xAxis.points = item.xAxis.points.concat([
              tmpX,
              realPaddingX,
              tmpX,
              realPaddingX - 5,
            ]);
            if (_config.type === "line") {
              tablePoints = tablePoints.concat([
                tmpX,
                realPaddingX,
                tmpX,
                _container.clientHeight - item.xAxis.defaltPadding,
              ]);
            }
            let xstr = "";
            if (item.xAxis.xAxisMarkFormatter) {
              xstr = item.xAxis.xAxisMarkFormatter(tmpXvalue);
            } else {
              xstr = tmpXvalue.toString();
            }
            item.xAxis.words.push({
              str: xstr,
              x: tmpX - _textCtx.measureText(xstr).width / 2,
              // 减去了字体高度和 小标签的高度
              y: _container.height - (realPaddingX - 10 - 5),
            });
            if (_config.type === "line") {
              item.xTablePoints = tablePoints;
            }
            // //console.log(item.xAxis.points)
          }
        }
        if (_config.type === "line") {
          _drawLineGroup(item.xTablePoints, _axisMatrix, {
            r: 0,
            g: 80 / 255,
            b: 0,
          });
          _drawLineGroup(item.yTablePoints, _axisMatrix, {
            r: 0,
            g: 80 / 255,
            b: 0,
          });
        }
      }
      // 绘制x轴
      _drawLineGroup(item.xAxis.points, _axisMatrix, item.xAxis.color);
      item.xAxis.words.forEach((word) => {
        _textCtx.fillText(word.str, word.x, word.y);
      });

      // 绘制y轴
      _drawLineGroup(item.yAxis.points, _axisMatrix, item.yAxis.color);
      item.yAxis.words.forEach((word) => {
        _textCtx.fillText(word.str, word.x, word.y);
      });
    });
  }

  // /**
  //  * 绘制线
  //  */
  // function _drawSeriesLine () {
  //   _Series.forEach((series, index) => {
  //       // 设置使用的着色器和viewport
  //     _gl.useProgram(_lineShaderProgram)
  //     _gl.viewport(series.yAxis.padding, series.xAxis.padding, _gl.canvas.width - series.yAxis.padding - series.yAxis.defaltPadding, _gl.canvas.height - series.xAxis.padding - series.xAxis.defaltPadding)

  //     if (!series._linesMatrix) {
  //       // 根据分辨率直接生成矩阵
  //       // eslint-disable-next-line no-undef
  //       var projectionMatrix = m3.projection(_gl.canvas.clientWidth - series.yAxis.padding - series.yAxis.defaltPadding, _gl.canvas.clientHeight - series.xAxis.padding - series.xAxis.defaltPadding)
  //       // 因为上面的方法生成的矩阵原点在左上方 需要原点在左下方,所以先沿y轴平移canvas高度(向上),在沿y轴翻转 (这样原点的坐标就在左下了)
  //       var translationMatrix = m3.translation(0, _gl.canvas.clientHeight - series.xAxis.padding - series.xAxis.defaltPadding)
  //       projectionMatrix = m3.multiply(projectionMatrix, translationMatrix)
  //       // scaling 绕原点翻转(-1 ~ 1)
  //       projectionMatrix = m3.multiply(projectionMatrix, m3.scaling(1, -1))
  //       series._linesMatrix = projectionMatrix
  //     }
  //     series.lines.forEach((line) => {
  //       if (line.transferedData.length === 0) {
  //           // 需要重新计算坐标
  //         for (let i = 0; i < line.data.length; i += 2) {
  //           let x = line.data[i]
  //           let y = line.data[i + 1]
  //           let newXPercent = ((x - series.xAxis.interval[0]) / (series.xAxis.interval[1] - series.xAxis.interval[0]))
  //           let transformedX = (_container.clientWidth - series.yAxis.padding - series.yAxis.defaltPadding) * newXPercent
  //           let newYPercent = ((y - series.yAxis.interval[0]) / (series.yAxis.interval[1] - series.yAxis.interval[0]))
  //           let transformedY = (_container.clientHeight - series.xAxis.padding - series.xAxis.defaltPadding) * newYPercent
  //           if (i === 0 || i === line.data.length - 2) {
  //             line.transferedData.push(transformedX)
  //             line.transferedData.push(transformedY)
  //           } else {
  //             line.transferedData.push(transformedX)
  //             line.transferedData.push(transformedY)
  //             line.transferedData.push(transformedX)
  //             line.transferedData.push(transformedY)
  //           }
  //         }
  //       }
  //       _drawLineGroup(line.transferedData, series._linesMatrix, line.color)
  //     })
  //   })
  // }

  /**
   * 绘制线
   */
  function _drawSeriesLine() {
    _Series.forEach((series, index) => {
      // 设置使用的着色器和viewport
      _gl.useProgram(_lineShaderProgram);
      _gl.viewport(
        series.yAxis.padding,
        series.xAxis.padding,
        _gl.canvas.width - series.yAxis.padding - series.yAxis.defaltPadding,
        _gl.canvas.height - series.xAxis.padding - series.xAxis.defaltPadding
      );

      if (!series._linesMatrix) {
        // 根据分辨率直接生成矩阵
        // eslint-disable-next-line no-undef
        let projectionMatrix = m3.projection(
          _gl.canvas.clientWidth -
            series.yAxis.padding -
            series.yAxis.defaltPadding,
          _gl.canvas.clientHeight -
            series.xAxis.padding -
            series.xAxis.defaltPadding
        );
        // 因为上面的方法生成的矩阵原点在左上方 需要原点在左下方,所以先沿y轴平移canvas高度(向上),在沿y轴翻转 (这样原点的坐标就在左下了)
        const translationMatrix = m3.translation(
          0,
          _gl.canvas.clientHeight -
            series.xAxis.padding -
            series.xAxis.defaltPadding
        );
        projectionMatrix = m3.multiply(projectionMatrix, translationMatrix);
        // scaling 绕原点翻转(-1 ~ 1)
        projectionMatrix = m3.multiply(projectionMatrix, m3.scaling(1, -1));

        const xTransfer =
          (series.xAxis.interval[1] - series.xAxis.interval[0]) /
          (_container.clientWidth -
            series.yAxis.padding -
            series.yAxis.defaltPadding);
        const yTransfer =
          (series.yAxis.interval[1] - series.yAxis.interval[0]) /
          (_container.clientHeight -
            series.xAxis.padding -
            series.xAxis.defaltPadding);
        projectionMatrix = m3.multiply(
          projectionMatrix,
          m3.scaling(1 / xTransfer, 1 / yTransfer)
        );
        projectionMatrix = m3.multiply(
          projectionMatrix,
          m3.translation(-series.xAxis.interval[0], -series.yAxis.interval[0])
        );
        series._linesMatrix = projectionMatrix;
      }
      // _drawLineGroup([0, 0, 546.13, 204, 546.13, 204, 0, 204, 546.13, 215, 546.13, 95, 546.13, 95, 0, 95], series._linesMatrix, {r: 1, g: 1, b: 1})
      series.lines.forEach((line) => {
        // if (line.transferedData.length === 0) {
        //   // 需要重新计算坐标
        //   for (let i = 0; i < line.data.length; i += 2) {
        //     let x = line.data[i]
        //     let y = line.data[i + 1]
        //     let newXPercent = ((x - series.xAxis.interval[0]) / (series.xAxis.interval[1] - series.xAxis.interval[0]))
        //     let transformedX = (_container.clientWidth - series.yAxis.padding - series.yAxis.defaltPadding) * newXPercent
        //     let newYPercent = ((y - series.yAxis.interval[0]) / (series.yAxis.interval[1] - series.yAxis.interval[0]))
        //     let transformedY = (_container.clientHeight - series.xAxis.padding - series.xAxis.defaltPadding) * newYPercent
        //     if (i === 0 || i === line.data.length - 2) {
        //       line.transferedData.push(transformedX)
        //       line.transferedData.push(transformedY)
        //     } else {
        //       line.transferedData.push(transformedX)
        //       line.transferedData.push(transformedY)
        //       line.transferedData.push(transformedX)
        //       line.transferedData.push(transformedY)
        //     }
        //   }
        // }
        if (line.visible) {
          _drawLineGroupWithLineStrip(
            line.data,
            series._linesMatrix,
            line.color
          );
        }
      });
    });
  }

  /**
   * 绘制鼠标拖动的矩形
   */
  function _drawSeriesMouseStrapRect() {
    _gl.viewport(0, 0, _gl.canvas.width, _gl.canvas.height);
    _Series.forEach((series) => {
      if (series.mouseStrapPoints && series.mouseStrapPoints.length !== 0) {
        // _drawLineGroup(series.mouseStrapPoints, _axisMatrix, {r: 1, g: 1, b: 1})
        _drawTransparentRect(series.mouseStrapPoints, _axisMatrix, {
          r: 1,
          g: 1,
          b: 1,
          a: 1,
        });
      }
    });
  }

  /**
   * 绘制鼠标左键拖动测量的矩形
   */
     function _drawSeriesMouseStrapMeasureRect() {
      _gl.viewport(0, 0, _gl.canvas.width, _gl.canvas.height);
      _Series.forEach((series) => {
        if (series.mouseStrapMeasure) {
          if(!series.mouseStrapMeasure.points || series.mouseStrapMeasure.points.length === 0){
            _clickedXaxisSeries.mouseStrapMeasure.points = []
            _clickedXaxisSeries.mouseStrapMeasure.points.push(series.mouseStrapMeasure.startX);
            _clickedXaxisSeries.mouseStrapMeasure.points.push(series.mouseStrapMeasure.startY);

            _clickedXaxisSeries.mouseStrapMeasure.points.push(series.mouseStrapMeasure.endX);
            _clickedXaxisSeries.mouseStrapMeasure.points.push(series.mouseStrapMeasure.startY);
            _clickedXaxisSeries.mouseStrapMeasure.points.push(series.mouseStrapMeasure.endX);
            _clickedXaxisSeries.mouseStrapMeasure.points.push(series.mouseStrapMeasure.endY);

            _clickedXaxisSeries.mouseStrapMeasure.points.push(series.mouseStrapMeasure.endX);
            _clickedXaxisSeries.mouseStrapMeasure.points.push(series.mouseStrapMeasure.endY);

            _clickedXaxisSeries.mouseStrapMeasure.points.push(series.mouseStrapMeasure.startX);
            _clickedXaxisSeries.mouseStrapMeasure.points.push(series.mouseStrapMeasure.startY);
            _clickedXaxisSeries.mouseStrapMeasure.points.push(series.mouseStrapMeasure.startX);
            _clickedXaxisSeries.mouseStrapMeasure.points.push(series.mouseStrapMeasure.endY);
            
            _clickedXaxisSeries.mouseStrapMeasure.words = []
          }
          
          // _drawLineGroup(series.mouseStrapPoints, _axisMatrix, {r: 1, g: 1, b: 1})
          _drawTransparentRect(series.mouseStrapMeasure.points, _axisMatrix, {
            r: 0,
            g: 1,
            b: 1,
            a: 1,
          });
          if (!series.mouseStrapMeasure.words || series.mouseStrapMeasure.words.length === 0) {
            const realStartYValue = _getRealYValueByYPixes(
              series.mouseStrapMeasure.startY,
              series
            );
            const realEndYValue = _getRealYValueByYPixes(
              series.mouseStrapMeasure.endY,
              series
            );
            const realStartXValue = _getRealXValueByXPixes(
              series.mouseStrapMeasure.startX,
              series
            );
            const realEndXValue = _getRealXValueByXPixes(
              series.mouseStrapMeasure.endX,
              series
            );
            series.mouseStrapMeasure.words = []
            let xStr = series.xAxis.xAxisMarkFormatter ? series.xAxis.xAxisMarkFormatter((realEndXValue - realStartXValue).toFixed(2)) :
              (realEndXValue - realStartXValue).toFixed(2).toString()
            let yStr = ''
            if(_config.type === 'pubu'){
              // 需要将realX转化成真实时间戳
              const startidx = series.yAxis.interval[1] - realStartYValue;
              const realstartY =
                series.yAxis.timeStamps[
                  series.yAxis.timeStamps.length - 1 - Math.round(startidx)
                ];

              const endidx = series.yAxis.interval[1] - realEndYValue;
              const realEndY =
                series.yAxis.timeStamps[
                  series.yAxis.timeStamps.length - 1 - Math.round(endidx)
                ];
              yStr = getmmssSSS(realstartY - realEndY)
              // 瀑布图测量的文字放在方框左边
              _textCtx.fillStyle = "rgba(0,255,255,0.5)";
              _textCtx.font = "15px sans-serif";
              series.mouseStrapMeasure.words.push({
                x: series.mouseStrapMeasure.startX - _textCtx.measureText(yStr).width,
                y:
                  _container.clientHeight -
                  (series.mouseStrapMeasure.startY +
                    (series.mouseStrapMeasure.endY - series.mouseStrapMeasure.startY) / 2),
                // str: series.yAxis.yAxisMarkFormatter
                //     ? series.yAxis.yAxisMarkFormatter((realEndYValue - realStartYValue).toFixed(2))
                //     : (realEndYValue - realStartYValue).toFixed(2).toString()
                str: yStr,
              })
            }else if(_config.type === 'line'){
              yStr = (realEndYValue - realStartYValue).toFixed(2).toString() + 'dBm'
              series.mouseStrapMeasure.words.push({
                x: series.mouseStrapMeasure.endX,
                y:
                  _container.clientHeight -
                  (series.mouseStrapMeasure.startY +
                    (series.mouseStrapMeasure.endY - series.mouseStrapMeasure.startY) / 2),
                // str: series.yAxis.yAxisMarkFormatter
                //     ? series.yAxis.yAxisMarkFormatter((realEndYValue - realStartYValue).toFixed(2))
                //     : (realEndYValue - realStartYValue).toFixed(2).toString()
                str: yStr,
              })
              series.mouseStrapMeasure.words.push({
                x: series.mouseStrapMeasure.startX + ( series.mouseStrapMeasure.endX - series.mouseStrapMeasure.startX) / 2 - 
                  _textCtx.measureText(xStr).width / 2,
                y: _container.clientHeight - series.mouseStrapMeasure.startY + 15,
                str: xStr,
              })
            }
            // series.mouseStrapMeasure.words = [
            //   {
            //     x: series.mouseStrapMeasure.endX,
            //     y:
            //       _container.clientHeight -
            //       (series.mouseStrapMeasure.startY +
            //         (series.mouseStrapMeasure.endY - series.mouseStrapMeasure.startY) / 2),
            //     // str: series.yAxis.yAxisMarkFormatter
            //     //     ? series.yAxis.yAxisMarkFormatter((realEndYValue - realStartYValue).toFixed(2))
            //     //     : (realEndYValue - realStartYValue).toFixed(2).toString()
            //     str: yStr,
            //   },
            //   {
            //     x: series.mouseStrapMeasure.startX + ( series.mouseStrapMeasure.endX - series.mouseStrapMeasure.startX) / 2 - 
            //       _textCtx.measureText(xStr).width / 2,
            //     y: _container.clientHeight - series.mouseStrapMeasure.endY + 15,
            //     str: xStr,
            //   },
            // ];
          }
          series.mouseStrapMeasure.words.forEach((word) => {
            _textCtx.fillStyle =
              "rgba(" +
              255 * series.measureTextColor.r +
              "," +
              255 * series.measureTextColor.g +
              "," +
              255 * series.measureTextColor.b +
              "," +
              255 * series.measureTextColor.a +
              ")";
            _textCtx.font = "15px sans-serif";
            _textCtx.fillText(word.str, word.x, word.y);
          });
        }
      });
    }

  /**
   * 绘制标记线
   */
  function _drawMarkLines() {
    _gl.useProgram(_lineShaderProgram);
    _gl.viewport(0, 0, _container.clientWidth, _container.clientHeight);

    _Series.forEach((series) => {
      series.xAxis.markLines.forEach((markLine) => {
        if (markLine.visible == false) {
          return;
        }
        if (markLine.points.length === 0) {
          if (
            markLine.value < series.xAxis.interval[0] ||
            markLine.value > series.xAxis.interval[1]
          ) {
            return;
          }
          // 计算点
          const transformedX = _getXPixesByXvalue(markLine.value, series);

          markLine.pixes = transformedX;
          markLine.points.push(transformedX);
          markLine.points.push(series.xAxis.padding);
          markLine.points.push(transformedX);
          markLine.points.push(
            _container.clientHeight - series.xAxis.defaltPadding
          );

          // _drawLineGroup(markLine.points, _axisMatrix, markLine.color)
          _drawYLineWithWidth(
            markLine.points[0],
            markLine.points[1],
            markLine.points[2],
            markLine.points[3],
            1,
            _axisMatrix,
            markLine.color
          );
        } else {
          // _drawLineGroup(markLine.points, _axisMatrix, markLine.color)

          _drawYLineWithWidth(
            markLine.points[0],
            markLine.points[1],
            markLine.points[2],
            markLine.points[3],
            1,
            _axisMatrix,
            markLine.color
          );
        }
      });
      series.yAxis.markLines.forEach((markLine) => {
        if (markLine.points.length === 0) {
          if (
            markLine.value < series.yAxis.interval[0] ||
            markLine.value > series.yAxis.interval[1]
          ) {
            return;
          }
          // 计算点
          const transformedY = _getYPixesByYvalue(markLine.value, series);
          markLine.pixes = transformedY;
          markLine.points.push(series.yAxis.padding);
          markLine.points.push(transformedY);
          markLine.points.push(
            _container.clientWidth - series.yAxis.defaltPadding
          );
          markLine.points.push(transformedY);

          // _drawLineGroup(markLine.points, _axisMatrix, markLine.color)
          _drawXLineWithWidth(
            markLine.points[0],
            markLine.points[1],
            markLine.points[2],
            markLine.points[3],
            1,
            _axisMatrix,
            markLine.color
          );
        } else {
          // _drawLineGroup(markLine.points, _axisMatrix, markLine.color)

          _drawXLineWithWidth(
            markLine.points[0],
            markLine.points[1],
            markLine.points[2],
            markLine.points[3],
            1,
            _axisMatrix,
            markLine.color
          );
        }
      });
    });
  }
  /**
   * 绘制x轴的标记区域
   */
  function _drawXMarkZones() {
    _Series.forEach((series) => {
      if (!series._linesMatrix) {
        // 根据分辨率直接生成矩阵
        // eslint-disable-next-line no-undef
        let projectionMatrix = m3.projection(
          _gl.canvas.clientWidth -
            series.yAxis.padding -
            series.yAxis.defaltPadding,
          _gl.canvas.clientHeight -
            series.xAxis.padding -
            series.xAxis.defaltPadding
        );
        // 因为上面的方法生成的矩阵原点在左上方 需要原点在左下方,所以先沿y轴平移canvas高度(向上),在沿y轴翻转 (这样原点的坐标就在左下了)
        const translationMatrix = m3.translation(
          0,
          _gl.canvas.clientHeight -
            series.xAxis.padding -
            series.xAxis.defaltPadding
        );
        projectionMatrix = m3.multiply(projectionMatrix, translationMatrix);
        // scaling 绕原点翻转(-1 ~ 1)
        projectionMatrix = m3.multiply(projectionMatrix, m3.scaling(1, -1));

        const xTransfer =
          (series.xAxis.interval[1] - series.xAxis.interval[0]) /
          (_container.clientWidth -
            series.yAxis.padding -
            series.yAxis.defaltPadding);
        const yTransfer =
          (series.yAxis.interval[1] - series.yAxis.interval[0]) /
          (_container.clientHeight -
            series.xAxis.padding -
            series.xAxis.defaltPadding);
        projectionMatrix = m3.multiply(
          projectionMatrix,
          m3.scaling(1 / xTransfer, 1 / yTransfer)
        );
        projectionMatrix = m3.multiply(
          projectionMatrix,
          m3.translation(-series.xAxis.interval[0], -series.yAxis.interval[0])
        );
        series._linesMatrix = projectionMatrix;
      }
      _gl.useProgram(_lineShaderProgram);
      _gl.viewport(
        series.yAxis.padding,
        series.xAxis.padding,
        _gl.canvas.width - series.yAxis.padding - series.yAxis.defaltPadding,
        _gl.canvas.height - series.xAxis.padding - series.xAxis.defaltPadding
      );

      if (
        !series.xAxis.markZonePoints ||
        series.xAxis.markZonePoints.length === 0
      ) {
        series.xAxis.markZoneWords = [];
        series.xAxis.markZonePointColors = [];
        series.xAxis.markZones.forEach((markZone) => {
          const transformedStartX = markZone.start;
          const transformedendX = markZone.end;

          const transformedstartY = series.yAxis.interval[0];
          const transformedendY = series.yAxis.interval[1];
          if (markZone.points.length === 0) {
            series.xAxis.markZonePoints = series.xAxis.markZonePoints.concat([
              transformedStartX,
              transformedstartY,
              transformedendX,
              transformedstartY,
              transformedStartX,
              transformedendY,
              transformedStartX,
              transformedendY,
              transformedendX,
              transformedendY,
              transformedendX,
              transformedstartY,
            ]);
            markZone.points = series.xAxis.markZonePoints;
            series.xAxis.markZonePointColors =
              series.xAxis.markZonePointColors.concat([
                markZone.color.r,
                markZone.color.g,
                markZone.color.b,
                markZone.color.a,
                markZone.color.r,
                markZone.color.g,
                markZone.color.b,
                markZone.color.a,
                markZone.color.r,
                markZone.color.g,
                markZone.color.b,
                markZone.color.a,
                markZone.color.r,
                markZone.color.g,
                markZone.color.b,
                markZone.color.a,
                markZone.color.r,
                markZone.color.g,
                markZone.color.b,
                markZone.color.a,
                markZone.color.r,
                markZone.color.g,
                markZone.color.b,
                markZone.color.a,
              ]);
            // 绘制两条有宽度的边框
            if (markZone.borderColor) {
              const width =
                (2 /
                  (_container.clientWidth -
                    series.yAxis.padding -
                    -series.yAxis.defaltPadding)) *
                (series.xAxis.interval[1] - series.xAxis.interval[0]);

              series.xAxis.markZonePoints = series.xAxis.markZonePoints.concat([
                transformedStartX - width,
                transformedstartY,
                transformedStartX,
                transformedstartY,
                transformedStartX - width,
                transformedendY,
                transformedStartX - width,
                transformedendY,
                transformedStartX,
                transformedendY,
                transformedStartX,
                transformedstartY,

                transformedendX,
                transformedstartY,
                transformedendX + width,
                transformedstartY,
                transformedendX,
                transformedendY,
                transformedendX,
                transformedendY,
                transformedendX + width,
                transformedendY,
                transformedendX + width,
                transformedstartY,
              ]);
              markZone.points = series.xAxis.markZonePoints;
              series.xAxis.markZonePointColors =
                series.xAxis.markZonePointColors.concat([
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,

                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                ]);
            }
            if (markZone.borderColor) {
            } else {
              // 添加在左右边界添加两条线
              series.xAxis.markZoneLRPoints =
                series.xAxis.markZoneLRPoints.concat([
                  transformedStartX,
                  transformedstartY,
                  transformedStartX,
                  transformedendY,
                  transformedendX,
                  transformedstartY,
                  transformedendX,
                  transformedendY,
                ]);
            }
            if (markZone.borderColor) {
            } else {
              series.xAxis.markZoneLRPointsColors =
                series.xAxis.markZoneLRPointsColors.concat([
                  markZone.color.r,
                  markZone.color.g,
                  markZone.color.b,
                  markZone.color.a,
                  markZone.color.r,
                  markZone.color.g,
                  markZone.color.b,
                  markZone.color.a,
                  markZone.color.r,
                  markZone.color.g,
                  markZone.color.b,
                  markZone.color.a,
                  markZone.color.r,
                  markZone.color.g,
                  markZone.color.b,
                  markZone.color.a,
                ]);
            }
          }

          const transformedRealEndX = _getXPixesByXvalueOnLineMatrix(
            markZone.end,
            series
          );
          series.xAxis.markZoneWords.push({
            x: transformedRealEndX + series.yAxis.padding,
            y: series.xAxis.defaltPadding + 15,
            str: markZone.str,
            // fillStyle:'rgb(' + markZone.color.r * 255 + ',' + markZone.color.g * 255 + ',' + markZone.color.b * 255 + ')'
            fillStyle: "rgb(255,255,255)",
          });
          // _drawTransparentRect(markZone.points, series._linesMatrix, {r: 1, g: 1, b: 1})
          // _drawTranglesWithVaringColor(markZone.points, series._linesMatrix,markZone.pointColors)
        });
      }
      if (
        series.xAxis.markZonePoints &&
        series.xAxis.markZonePoints.length > 0
      ) {
        _drawTranglesWithVaringColor(
          series.xAxis.markZonePoints,
          series._linesMatrix,
          series.xAxis.markZonePointColors
        );
        _drawLineGroupWithVaringColor(
          series.xAxis.markZoneLRPoints,
          series._linesMatrix,
          series.xAxis.markZoneLRPointsColors
        );
      }
      // series.xAxis.markZonesHighLight.forEach((markZoneHighLight) => {
      //   let transformedStartX = markZoneHighLight.start
      //   let transformedendX = markZoneHighLight.end

      //   let transformedstartY = series.yAxis.interval[0]
      //   let transformedendY = series.yAxis.interval[1]
      //   if (markZoneHighLight.points.length === 0) {
      //     markZoneHighLight.points = [
      //       transformedStartX, transformedstartY,
      //       transformedendX, transformedstartY,
      //       transformedStartX, transformedendY,
      //       transformedStartX, transformedendY,
      //       transformedendX, transformedendY,
      //       transformedendX, transformedstartY
      //     ]
      //   }
      //   let transformedRealEndX = _getXPixesByXvalueOnLineMatrix(markZoneHighLight.end, series)
      //   series.xAxis.markZoneWords.push({
      //     x: transformedRealEndX + series.yAxis.padding,
      //     y:  series.xAxis.defaltPadding + 15,
      //     str: markZoneHighLight.str,
      //     fillStyle:'rgb(0,255,0)'
      //   })
      //   _drawTransparentRect(markZoneHighLight.points, series._linesMatrix, {r: 0, g: 1, b: 0})
      //   _drawLineGroup([
      //     transformedStartX,transformedstartY,
      //     transformedStartX,transformedendY,
      //     transformedendX,transformedstartY,
      //     transformedendX,transformedendY,
      //   ],series._linesMatrix,{r:1,g:1,b:1})
      // })
      if (series.xAxis.showMarkZoneWord) {
        // 绘制文字
        series.xAxis.markZoneWords.forEach((markZoneWord) => {
          if (
            markZoneWord.x >
              _container.clientWidth - series.yAxis.defaltPadding ||
            markZoneWord.x < series.yAxis.padding
          ) {
            return;
          }
          _textCtx.fillStyle = markZoneWord.fillStyle;
          _textCtx.font = "12px sans-serif";
          _textCtx.fillText(markZoneWord.str, markZoneWord.x, markZoneWord.y);
        });
      }

      // 绘制黑名单的数据
      if (
        !series.xAxis.markZonesOfBlackListPoints ||
        series.xAxis.markZonesOfBlackListPoints.length === 0
      ) {
        series.xAxis.markZonesOfBlackListWords = [];
        series.xAxis.markZonesOfBlackListPointColors = [];
        series.xAxis.markZonesOfBlackList.forEach((markZone) => {
          const transformedStartX = markZone.start;
          const transformedendX = markZone.end;

          const transformedstartY = series.yAxis.interval[0];
          const transformedendY = series.yAxis.interval[1];
          if (markZone.points.length === 0) {
            series.xAxis.markZonesOfBlackListPoints =
              series.xAxis.markZonesOfBlackListPoints.concat([
                transformedStartX,
                transformedstartY,
                transformedendX,
                transformedstartY,
                transformedStartX,
                transformedendY,
                transformedStartX,
                transformedendY,
                transformedendX,
                transformedendY,
                transformedendX,
                transformedstartY,
              ]);
            markZone.points = [
              transformedStartX,
              transformedstartY,
              transformedendX,
              transformedstartY,
              transformedStartX,
              transformedendY,
              transformedStartX,
              transformedendY,
              transformedendX,
              transformedendY,
              transformedendX,
              transformedstartY,
            ];
            series.xAxis.markZonesOfBlackListPointColors =
              series.xAxis.markZonesOfBlackListPointColors.concat([
                markZone.color.r,
                markZone.color.g,
                markZone.color.b,
                markZone.color.a,
                markZone.color.r,
                markZone.color.g,
                markZone.color.b,
                markZone.color.a,
                markZone.color.r,
                markZone.color.g,
                markZone.color.b,
                markZone.color.a,
                markZone.color.r,
                markZone.color.g,
                markZone.color.b,
                markZone.color.a,
                markZone.color.r,
                markZone.color.g,
                markZone.color.b,
                markZone.color.a,
                markZone.color.r,
                markZone.color.g,
                markZone.color.b,
                markZone.color.a,
              ]);
            // 绘制两条有宽度的边框
            if (markZone.borderColor) {
              const width =
                (2 /
                  (_container.clientWidth -
                    series.yAxis.padding -
                    -series.yAxis.defaltPadding)) *
                (series.xAxis.interval[1] - series.xAxis.interval[0]);

              series.xAxis.markZonesOfBlackListPoints =
                series.xAxis.markZonesOfBlackListPoints.concat([
                  transformedStartX - width,
                  transformedstartY,
                  transformedStartX,
                  transformedstartY,
                  transformedStartX - width,
                  transformedendY,
                  transformedStartX - width,
                  transformedendY,
                  transformedStartX,
                  transformedendY,
                  transformedStartX,
                  transformedstartY,

                  transformedendX,
                  transformedstartY,
                  transformedendX + width,
                  transformedstartY,
                  transformedendX,
                  transformedendY,
                  transformedendX,
                  transformedendY,
                  transformedendX + width,
                  transformedendY,
                  transformedendX + width,
                  transformedstartY,
                ]);
              markZone.points = [
                transformedStartX - width,
                transformedstartY,
                transformedStartX,
                transformedstartY,
                transformedStartX - width,
                transformedendY,
                transformedStartX - width,
                transformedendY,
                transformedStartX,
                transformedendY,
                transformedStartX,
                transformedstartY,

                transformedendX,
                transformedstartY,
                transformedendX + width,
                transformedstartY,
                transformedendX,
                transformedendY,
                transformedendX,
                transformedendY,
                transformedendX + width,
                transformedendY,
                transformedendX + width,
                transformedstartY,
              ];
              series.xAxis.markZonesOfBlackListPointColors =
                series.xAxis.markZonesOfBlackListPointColors.concat([
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,

                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                  markZone.borderColor.r,
                  markZone.borderColor.g,
                  markZone.borderColor.b,
                  markZone.borderColor.a,
                ]);
            }
            if (markZone.borderColor) {
            } else {
              // 添加在左右边界添加两条线
              series.xAxis.markZonesOfBlackListLRPoints =
                series.xAxis.markZonesOfBlackListLRPoints.concat([
                  transformedStartX,
                  transformedstartY,
                  transformedStartX,
                  transformedendY,
                  transformedendX,
                  transformedstartY,
                  transformedendX,
                  transformedendY,
                ]);
            }
            if (markZone.borderColor) {
            } else {
              series.xAxis.markZonesOfBlackListLRPointsColors =
                series.xAxis.markZonesOfBlackListLRPointsColors.concat([
                  markZone.color.r,
                  markZone.color.g,
                  markZone.color.b,
                  markZone.color.a,
                  markZone.color.r,
                  markZone.color.g,
                  markZone.color.b,
                  markZone.color.a,
                  markZone.color.r,
                  markZone.color.g,
                  markZone.color.b,
                  markZone.color.a,
                  markZone.color.r,
                  markZone.color.g,
                  markZone.color.b,
                  markZone.color.a,
                ]);
            }
          }
          const transformedRealEndX = _getXPixesByXvalueOnLineMatrix(
            markZone.end,
            series
          );
          series.xAxis.markZonesOfBlackListWords.push({
            x: transformedRealEndX + series.yAxis.padding,
            y: series.xAxis.defaltPadding + 15,
            str: markZone.str,
            fillStyle: "rgb(255,255,255)",
          });
        });
      }
      if (
        series.xAxis.markZonesOfBlackListPoints &&
        series.xAxis.markZonesOfBlackListPoints.length > 0
      ) {
        _drawTranglesWithVaringColor(
          series.xAxis.markZonesOfBlackListPoints,
          series._linesMatrix,
          series.xAxis.markZonesOfBlackListPointColors
        );
        _drawLineGroupWithVaringColor(
          series.xAxis.markZonesOfBlackListLRPoints,
          series._linesMatrix,
          series.xAxis.markZonesOfBlackListLRPointsColors
        );
      }
      // 绘制文字
      series.xAxis.markZonesOfBlackListWords.forEach((markZoneWord) => {
        if (
          markZoneWord.x >
            _container.clientWidth - series.yAxis.defaltPadding ||
          markZoneWord.x < series.yAxis.padding
        ) {
          return;
        }
        _textCtx.fillStyle = markZoneWord.fillStyle;
        _textCtx.font = "12px sans-serif";
        _textCtx.fillText(markZoneWord.str, markZoneWord.x, markZoneWord.y);
      });
    });
  }

  /**
   * 绘制矩形标记区域
   */
  function _drawRectMarkZone() {
    _Series.forEach((series) => {
      if (
        series.rectMarkZonepoints.length === 0 &&
        series.rectMarkZone.length !== 0
      ) {
        if (!series._linesMatrix) {
          // 根据分辨率直接生成矩阵
          // eslint-disable-next-line no-undef
          let projectionMatrix = m3.projection(
            _gl.canvas.clientWidth -
              series.yAxis.padding -
              series.yAxis.defaltPadding,
            _gl.canvas.clientHeight -
              series.xAxis.padding -
              series.xAxis.defaltPadding
          );
          // 因为上面的方法生成的矩阵原点在左上方 需要原点在左下方,所以先沿y轴平移canvas高度(向上),在沿y轴翻转 (这样原点的坐标就在左下了)
          const translationMatrix = m3.translation(
            0,
            _gl.canvas.clientHeight -
              series.xAxis.padding -
              series.xAxis.defaltPadding
          );
          projectionMatrix = m3.multiply(projectionMatrix, translationMatrix);
          // scaling 绕原点翻转(-1 ~ 1)
          projectionMatrix = m3.multiply(projectionMatrix, m3.scaling(1, -1));
          series._linesMatrix = projectionMatrix;
        }
        _gl.useProgram(_lineShaderProgram);
        _gl.viewport(
          series.yAxis.padding,
          series.xAxis.padding,
          _gl.canvas.width - series.yAxis.padding - series.yAxis.defaltPadding,
          _gl.canvas.height - series.xAxis.padding - series.xAxis.defaltPadding
        );

        // 清空文字
        series.markZoneWords = [];

        series.rectMarkZone.forEach((markZone) => {
          if (markZone.endY < series.yAxis.interval[0]) {
            // 不在区域内
            return;
          }
          const transformedStartX = _getXPixesByXvalueOnLineMatrix(
            markZone.startX,
            series
          );
          const transformedEndX = _getXPixesByXvalueOnLineMatrix(
            markZone.endX,
            series
          );
          const transformedStartY = _getYPixesByYvalueOnLineMatrix(
            markZone.startY,
            series
          );
          const transformedEndY = _getYPixesByYvalueOnLineMatrix(
            markZone.endY,
            series
          );

          const width = 1;
          // series.rectMarkZonepoints = series.rectMarkZonepoints.concat([
          //   transformedStartX, transformedStartY + width / 2,
          //   transformedStartX, transformedStartY - width / 2,
          //   transformedendX, transformedStartY + width / 2,
          //   transformedStartX, transformedStartY - width / 2,
          //   transformedendX, transformedStartY + width / 2,
          //   transformedendX, transformedStartY - width / 2,
          //   transformedStartX, transformedEndY + width / 2,
          //   transformedStartX, transformedEndY - width / 2,
          //   transformedendX, transformedEndY + width / 2,
          //   transformedStartX, transformedEndY - width / 2,
          //   transformedendX, transformedEndY + width / 2,
          //   transformedendX, transformedEndY - width / 2,

          //   transformedStartX + width / 2, transformedStartY,
          //   transformedStartX + width / 2, transformedEndY,
          //   transformedStartX - width / 2, transformedStartY,
          //   transformedStartX + width / 2, transformedEndY,
          //   transformedStartX - width / 2, transformedStartY,
          //   transformedStartX - width / 2, transformedEndY,
          //   transformedendX + width / 2, transformedStartY,
          //   transformedendX + width / 2, transformedEndY,
          //   transformedendX - width / 2, transformedStartY,
          //   transformedendX + width / 2, transformedEndY,
          //   transformedendX - width / 2, transformedStartY,
          //   transformedendX - width / 2, transformedEndY
          // ])
          series.rectMarkZonepoints = series.rectMarkZonepoints.concat([
            transformedStartX,
            transformedStartY,
            transformedEndX,
            transformedEndY,
            transformedStartX,
            transformedEndY,

            transformedStartX,
            transformedStartY,
            transformedEndX,
            transformedStartY,
            transformedEndX,
            transformedEndY,
          ]);
          // series.markZoneWords.push({
          //   x: transformedEndX + series.yAxis.padding,
          //   y: _container.clientHeight - (transformedEndY + series.xAxis.padding) + 10,
          //   str: markZone.str
          // })
        });
      }
      if (series.rectMarkZone.length !== 0) {
        _drawTransparentRect(series.rectMarkZonepoints, series._linesMatrix, {
          r: 1,
          g: 1,
          b: 1,
        });
        // _createBuffer(series.rectMarkZonepoints)
        // _gl.useProgram(_lineShaderProgram)
        // _gl.enableVertexAttribArray(_linePositionAttributeLocation)
        // // size=2表示每次迭代读取两个数据，即x和y。由于顶点着色器中gl_Position的类型是vec4，包含x,y,z,w四个数据，而这里只需要前两个x和y。
        // // type=gl_FLOAT表示使用的是32为浮点类型的数据。
        // // normalize=false表示不需要归一化数据。
        // // offset=0表示从缓冲区的开始位置读取数据。
        // _gl.vertexAttribPointer(_linePositionAttributeLocation, 2, _gl.FLOAT, false, 0, 0)

        // // 设置颜色
        // _gl.uniform4f(_lineFragColor, 1, 1, 1, 1)

        // // 设置变换矩阵
        // _gl.uniformMatrix3fv(_linematrixLocation, false, series._linesMatrix)

        // _gl.drawArrays(_gl.TRIANGLES, 0, series.rectMarkZonepoints.length / 2)

        // // 绘制文字
        // series.markZoneWords.forEach((markZoneWord) => {
        //   _textCtx.fillStyle = 'rgb(255,255,255)'
        //   _textCtx.font = '15px sans-serif'
        //   _textCtx.fillText(markZoneWord.str, markZoneWord.x, markZoneWord.y)
        // })
      }
    });
  }

  function _drawImage2D() {
    _Series.forEach((series) => {
      _gl.useProgram(_imageProgram);
      _gl.viewport(
        series.yAxis.padding,
        series.xAxis.padding,
        _container.clientWidth -
          series.yAxis.padding -
          series.yAxis.defaltPadding,
        _container.clientHeight -
          series.xAxis.padding -
          series.xAxis.defaltPadding
      );

      const imageNum = _imageList.length;
      // 每张图片所占的宽度
      // const imageWidth = (_gl.canvas.clientWidth -
      //   series.yAxis.padding -
      //   series.yAxis.defaltPadding) / imageNum
      let imageOffset = 0;
      _imageList.forEach((image, index) => {
        if (!image._rectinfo) {
          const perc = image.imageColumn / series.column;
          const imageWidth =
            perc *
            (_gl.canvas.clientWidth -
              series.yAxis.padding -
              series.yAxis.defaltPadding);
          const rectInfo = {};
          // 计算x轴的缩放和平移
          // x轴需要平移的距离 例如 原间距[0,100] 现间距[10,20]
          let xTransfer = 0;
          if (
            !series.showAllData &&
            (series.xAxis.interval[0] !== series.xAxis.oldInterval[0] ||
              series.xAxis.interval[1] !== series.xAxis.oldInterval[1])
          ) {
            // x轴缩放了 并且series不一直展示所有数据 对图像进行伸缩
            const percent =
              (series.xAxis.interval[1] - series.xAxis.interval[0]) /
              (series.xAxis.oldInterval[1] - series.xAxis.oldInterval[0]);
            // //console.log(percent)
            // 比如x轴缩放了1/10 那么图像的x轴长度要增长10倍
            rectInfo.rectangle = [
              imageOffset,
              0,
              imageWidth / percent,
              _gl.canvas.clientHeight -
                series.xAxis.padding -
                series.xAxis.defaltPadding,
            ];
            imageOffset += imageWidth / percent;
            // 计算出偏移量
            const tmp =
              ((series.xAxis.interval[0] - series.xAxis.oldInterval[0]) *
                ((_container.clientWidth -
                  series.yAxis.padding -
                  series.yAxis.defaltPadding) /
                  (series.xAxis.oldInterval[1] -
                    series.xAxis.oldInterval[0]))) /
              percent;
            xTransfer = tmp;
          } else {
            // 没有缩放
            rectInfo.rectangle = [
              imageOffset,
              0,
              imageWidth,
              _gl.canvas.clientHeight -
                series.xAxis.padding -
                series.xAxis.defaltPadding,
            ];

            imageOffset += imageWidth;
          }
          rectInfo.xTransfer = xTransfer;
          series.xTransfer = xTransfer;

          // 计算y轴的缩放和平移
          let yTransfer = 0;
          if (
            series.yAxis.interval[0] !== series.yAxis.oldInterval[0] ||
            series.yAxis.interval[1] !== series.yAxis.oldInterval[1]
          ) {
            // y轴缩放了
            const percent =
              (series.yAxis.interval[1] - series.yAxis.interval[0]) /
              (series.yAxis.oldInterval[1] - series.yAxis.oldInterval[0]);
            // 对rect的高度进行缩放
            rectInfo.rectangle[3] =
              (_gl.canvas.clientHeight -
                series.xAxis.padding -
                series.xAxis.defaltPadding) /
              percent;
            // 计算出偏移量
            const tmp =
              ((series.yAxis.interval[1] - series.yAxis.oldInterval[1]) *
                ((_container.clientHeight -
                  series.xAxis.padding -
                  series.xAxis.defaltPadding) /
                  (series.yAxis.oldInterval[1] -
                    series.yAxis.oldInterval[0]))) /
              percent;
            yTransfer = tmp;
          } else {
            // y轴没有缩放
          }

          series.yTransfer = yTransfer;
          image._rectinfo = rectInfo;

          _setRectangle(
            _gl,
            image._rectinfo.rectangle[0],
            image._rectinfo.rectangle[1],
            image._rectinfo.rectangle[2],
            image._rectinfo.rectangle[3]
          );
        } else {
          _setRectangle(
            _gl,
            image._rectinfo.rectangle[0],
            image._rectinfo.rectangle[1],
            image._rectinfo.rectangle[2],
            image._rectinfo.rectangle[3]
          );
        }
        // Turn on the position attribute
        _gl.enableVertexAttribArray(_imagePositionAttributeLocation);

        // Tell the position attribute how to get data out of positionBuffer (ARRAY_BUFFER)
        const size = 2; // 2 components per iteration
        const type = _gl.FLOAT; // the data is 32bit floats
        const normalize = false; // don't normalize the data
        const stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
        const offset = 0; // start at the beginning of the buffer
        _gl.vertexAttribPointer(
          _imagePositionAttributeLocation,
          size,
          type,
          normalize,
          stride,
          offset
        );

        // provide texture coordinates for the rectangle.
        if (series.direction === "topToBottom") {
          _createBuffer2([
            0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0,
          ]);
        } else if (series.direction === "rightToLeft") {
          _createBuffer2([
            1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0,
          ]);
        }
        // 向上
        // _createBuffer([
        //   0.0, 1.0,
        //   1.0, 1.0,
        //   0.0, 0.0,
        //   0.0, 0.0,
        //   1.0, 1.0,
        //   1.0, 0.0
        // ])
        // 从左边到右边
        // _createBuffer([
        //   1.0, 0.0,
        //   1.0, 1.0,
        //   0.0, 0.0,
        //   0.0, 0.0,
        //   1.0, 1.0,
        //   0.0, 1.0
        // ])
        // 从右边到左边
        // _createBuffer([
        //   1.0, 1.0,
        //   1.0, 0.0,
        //   0.0, 1.0,
        //   0.0, 1.0,
        //   1.0, 0.0,
        //   0.0, 0.0
        // ])
        _gl.enableVertexAttribArray(_imageTexcoordAttributeLocation);

        _gl.vertexAttribPointer(
          _imageTexcoordAttributeLocation,
          2,
          _gl.FLOAT,
          false,
          0,
          0
        );
        if (!_imgTexure) {
          _imgTexure = _gl.createTexture();
          _gl.bindTexture(_gl.TEXTURE_2D, _imgTexure);

          // Set the parameters so we can render any size image.
          _gl.texParameteri(
            _gl.TEXTURE_2D,
            _gl.TEXTURE_WRAP_S,
            _gl.CLAMP_TO_EDGE
          );
          _gl.texParameteri(
            _gl.TEXTURE_2D,
            _gl.TEXTURE_WRAP_T,
            _gl.CLAMP_TO_EDGE
          );
          // 邻近过滤  GL_NEAREST:OpenGL会选择纹理像素中心点最接近纹理坐标的那个像素
          // 线性过滤 GL_LINEAR:它会基于纹理坐标附近的纹理像素，计算出一个插值，近似出这些纹理像素之间的颜色。
          _gl.texParameteri(
            _gl.TEXTURE_2D,
            _gl.TEXTURE_MIN_FILTER,
            // _gl.NEAREST
            _gl.LINEAR
          );
          _gl.texParameteri(
            _gl.TEXTURE_2D,
            _gl.TEXTURE_MAG_FILTER,
            // _gl.NEAREST
            _gl.LINEAR
          );
        }
        // 获取最大纹理尺寸
        // console.log('最大纹理尺寸:', _gl.getParameter(_gl.MAX_TEXTURE_SIZE)) // 纹理的最大宽度或最大高度
        // Upload the image into the texture.
        // 将数据加载到纹理对象中
        _gl.texImage2D(
          _gl.TEXTURE_2D, // 目标纹理，可以是 gl.TEXTURE_2D 或 gl.TEXTURE_CUBE_MAP
          0, // 纹理级别，0表示基本级别
          _gl.RGBA, // 纹理的内部格式
          image.imageColumn, // 纹理的宽度
          series.row, // 纹理的高度
          0, // 边框大小，必须为0或1
          _gl.RGBA, // 纹理的像素数据格式 gl.RGBA 或 gl.RGB
          _gl.UNSIGNED_BYTE, // 数据类型
          image.imageDataUnit8 // 包含纹理像素数据的 ArrayBufferView 或 ImageData 对象
        );

        if (!series._projectionMatrix) {
          series._projectionMatrix = m3.projection(
            _gl.canvas.clientWidth -
              series.yAxis.padding -
              series.yAxis.defaltPadding,
            _gl.canvas.clientHeight -
              series.xAxis.padding -
              series.xAxis.defaltPadding
          );
          // x轴平移 - xTransfer 保持图像最左边的点坐标正好是x轴最小值的位置
          const translationMatrix = m3.translation(
            -series.xTransfer,
            series.yTransfer
          );
          series._projectionMatrix = m3.multiply(
            series._projectionMatrix,
            translationMatrix
          );
          // // scaling 绕原点翻转(-1 ~ 1)
          // projectionMatrix = m3.multiply(projectionMatrix, m3.scaling(1, -1))
          // //console.log(projectionMatrix)
          // _axisMatrix = projectionMatrix
          // projectionMatrix = m3.multiply(projectionMatrix, m3.translation(_Series[0].yAxis.padding, _Series[0].xAxis.defaltPadding))
        }
        _gl.uniformMatrix3fv(
          _imageMatrixLocation,
          false,
          series._projectionMatrix
        );

        _gl.drawArrays(_gl.TRIANGLES, 0, 6);
      });
    });
  }

  /**
   * 绘制瀑布图当前使用的色带
   */
  function _drawWaterColors() {
    _Series.forEach((series) => {
      if (!series.showColors) {
        return;
      }
      const num = 1;
      const padding = 5;
      const startY = series.xAxis.padding;
      const endY = _container.clientHeight - series.xAxis.defaltPadding;

      const startX =
        _container.clientWidth - series.yAxis.defaltPadding + padding;
      const endX = _container.clientWidth - padding;
      // 遍历色带
      if (series.waterColors && series.waterColors.length > 0) {
        const oneHeight = (endY - startY) / series.waterColors.length;
        const startPosition = startY;

        let points = [];
        let colors = [];
        for (let i = 0; i < series.waterColors.length; i++) {
          points = points.concat([
            startX,
            startPosition + i * oneHeight,
            endX,
            startPosition + i * oneHeight + oneHeight,
            startX,
            startPosition + i * oneHeight + oneHeight,
            startX,
            startPosition + i * oneHeight,
            endX,
            startPosition + i * oneHeight + oneHeight,
            endX,
            startPosition + i * oneHeight,
          ]);
          const color = series.waterColors[i];
          colors = colors.concat([
            color.R / 255,
            color.G / 255,
            color.B / 255,
            1,
            color.R / 255,
            color.G / 255,
            color.B / 255,
            1,
            color.R / 255,
            color.G / 255,
            color.B / 255,
            1,
            color.R / 255,
            color.G / 255,
            color.B / 255,
            1,
            color.R / 255,
            color.G / 255,
            color.B / 255,
            1,
            color.R / 255,
            color.G / 255,
            color.B / 255,
            1,
          ]);
        }
        _drawTranglesWithVaringColor(points, _axisMatrix, colors);
      }
      // let points = [
      //   startX,startY,
      //   endX,endY,
      //   startX,endY,
      //   startX,startY,
      //   endX,endY,
      //   endX,startY
      // ]
      // let colors = [
      //   0,255,255,1,
      //   0,255,255,1,
      //   0,255,255,1,
      //   0,255,255,1,
      //   0,255,255,1,
      //   0,255,255,1,
      // ]
      // _drawTranglesWithVaringColor(points,_axisMatrix,colors)
    });
  }

  /**
   * 绘制x轴测量的标记
   */
  function _drawMeasure() {
    _Series.forEach((series) => {
      _gl.useProgram(_lineShaderProgram);

      _gl.viewport(0, 0, _gl.canvas.width, _gl.canvas.height);
      if (series.SNRMeasureOpen) {
        if (series.SNRMeasure) {
        } else {
          // 设置到屏幕中间
          series.SNRMeasure = {
            type: "SNR",
            startX:
              (_container.clientWidth -
                series.yAxis.padding -
                series.yAxis.defaltPadding) /
                2 -
              100 +
              series.yAxis.padding,
            endX:
              (_container.clientWidth -
                series.yAxis.padding -
                series.yAxis.defaltPadding) /
                2 +
              100 +
              series.yAxis.padding,
            startY:
              (_container.clientHeight -
                series.xAxis.padding -
                series.xAxis.defaltPadding) /
                2 -
              50 +
              series.xAxis.padding,
            endY:
              (_container.clientHeight -
                series.xAxis.padding -
                series.xAxis.defaltPadding) /
                2 +
              50 +
              series.xAxis.padding,
            points: [],
            words: [],
          };
        }
        if (
          !series.SNRMeasure.points ||
          series.SNRMeasure.points.length === 0
        ) {
          const points = [
            series.SNRMeasure.startX,
            series.SNRMeasure.startY,
            series.SNRMeasure.startX,
            series.SNRMeasure.endY,
            series.SNRMeasure.endX,
            series.SNRMeasure.endY,

            series.SNRMeasure.endX,
            series.SNRMeasure.endY,
            series.SNRMeasure.startX,
            series.SNRMeasure.startY,
            series.SNRMeasure.endX,
            series.SNRMeasure.startY,
          ];
          series.SNRMeasure.points = points;
        }
        _drawTransparentRect(series.SNRMeasure.points, _axisMatrix, {
          r: 0,
          g: 1,
          b: 1,
        });
        if (!series.SNRMeasure.words || series.SNRMeasure.words.length === 0) {
          const realStartYValue = _getRealYValueByYPixes(
            series.SNRMeasure.startY,
            series
          );
          const realEndYValue = _getRealYValueByYPixes(
            series.SNRMeasure.endY,
            series
          );
          const realStartXValue = _getRealXValueByXPixes(
            series.SNRMeasure.startX,
            series
          );
          const realEndXValue = _getRealXValueByXPixes(
            series.SNRMeasure.endX,
            series
          );

          let xStr = series.xAxis.xAxisMarkFormatter ? series.xAxis.xAxisMarkFormatter((realEndXValue - realStartXValue).toFixed(2)) :
            (realEndXValue - realStartXValue).toFixed(2).toString()
          series.SNRMeasure.words = [
            {
              x: series.SNRMeasure.endX,
              y:
                _container.clientHeight -
                (series.SNRMeasure.startY +
                  (series.SNRMeasure.endY - series.SNRMeasure.startY) / 2),
              // str: series.yAxis.yAxisMarkFormatter
              //     ? series.yAxis.yAxisMarkFormatter((realEndYValue - realStartYValue).toFixed(2))
              //     : (realEndYValue - realStartYValue).toFixed(2).toString()
              str: (realEndYValue - realStartYValue).toFixed(2).toString() + 'dBm',
            },
            {
              x: series.SNRMeasure.startX + ( series.SNRMeasure.endX - series.SNRMeasure.startX) / 2 - 
                _textCtx.measureText(xStr).width / 2,
              y: _container.clientHeight - series.SNRMeasure.endY + 15,
              str: xStr,
            },
          ];
        }
        series.SNRMeasure.words.forEach((word) => {
          _textCtx.fillStyle =
            "rgba(" +
            255 * series.measureTextColor.r +
            "," +
            255 * series.measureTextColor.g +
            "," +
            255 * series.measureTextColor.b +
            "," +
            255 * series.measureTextColor.a +
            ")";
          _textCtx.font = "15px sans-serif";
          _textCtx.fillText(word.str, word.x, word.y);
        });
      }
      if (series.freqMeasureOpen) {
        if (series.freqMeasure) {
        } else {
          // 设置到屏幕中间
          series.freqMeasure = {
            type: "freq",
            startX:
              (_container.clientWidth -
                series.yAxis.padding -
                series.yAxis.defaltPadding) /
                2 -
              100 +
              series.yAxis.padding,
            endX:
              (_container.clientWidth -
                series.yAxis.padding -
                series.yAxis.defaltPadding) /
                2 +
              100 +
              series.yAxis.padding,
            startY: series.xAxis.padding,
            endY: _container.clientHeight - series.xAxis.defaltPadding,
            points: [],
            words: [],
          };
        }
        if (
          !series.freqMeasure.points ||
          series.freqMeasure.points.length === 0
        ) {
          const points = [
            series.freqMeasure.startX,
            series.freqMeasure.startY,
            series.freqMeasure.startX,
            series.freqMeasure.endY,
            series.freqMeasure.endX,
            series.freqMeasure.endY,

            series.freqMeasure.endX,
            series.freqMeasure.endY,
            series.freqMeasure.startX,
            series.freqMeasure.startY,
            series.freqMeasure.endX,
            series.freqMeasure.startY,
          ];
          series.freqMeasure.points = points;
        }
        _drawTransparentRect(series.freqMeasure.points, _axisMatrix, {
          r: 0,
          g: 1,
          b: 1,
        });
        if (
          !series.freqMeasure.words ||
          series.freqMeasure.words.length === 0
        ) {
          const realStartXValue = _getRealXValueByXPixes(
            series.freqMeasure.startX,
            series
          );
          const realEndXValue = _getRealXValueByXPixes(
            series.freqMeasure.endX,
            series
          );
          series.freqMeasure.words = [
            {
              x:
                series.freqMeasure.startX +
                (series.freqMeasure.endX - series.freqMeasure.startX) / 2 -
                _textCtx.measureText(
                  (realEndXValue - realStartXValue).toFixed(2)
                ).width /
                  2,
              y: series.xAxis.defaltPadding + 15,
              str: series.xAxis.xAxisMarkFormatter
                ? series.xAxis.xAxisMarkFormatter(
                    (realEndXValue - realStartXValue).toFixed(2)
                  ) 
                : (realEndXValue - realStartXValue).toFixed(2).toString(),
            },
          ];
        }
        series.freqMeasure.words.forEach((word) => {
          _textCtx.fillStyle =
            "rgba(" +
            255 * series.measureTextColor.r +
            "," +
            255 * series.measureTextColor.g +
            "," +
            255 * series.measureTextColor.b +
            "," +
            255 * series.measureTextColor.a +
            ")";
          _textCtx.font = "15px sans-serif";
          _textCtx.fillText(word.str + 'MHz', word.x, word.y);
        });
      }
      if (series.kdCollectionOpen) {
        if (series.kdCollection) {
          // if(!series.kdCollection.points || series.kdCollection.points.length === 0){
          //   let kdCollectionPositionValue = series.kdCollection.kdCollectionPositionValue
          //   let kdCollectionPosition = _getXPixesByXvalue(kdCollectionPositionValue,series)
          //   //console.log("kdCollectionPosition:"+kdCollectionPosition)
          //   let collectonZoneWidth = (series.kdCollectionWidth/(series.xAxis.interval[1] - series.xAxis.interval[0])) * (_container.clientWidth - series.yAxis.padding  - series.yAxis.defaltPadding)
          //   series.kdCollection.startX = kdCollectionPosition - collectonZoneWidth/2 + series.yAxis.padding
          //   series.kdCollection.endX = kdCollectionPosition + collectonZoneWidth/2 + series.yAxis.padding
          //   series.kdCollection.startY = series.xAxis.padding
          //   series.kdCollection.endY = _container.clientHeight  - series.xAxis.defaltPadding
          //   //console.log("kdCollectionPositionValue:"+kdCollectionPositionValue)
          // }
        } else {
          // todo 可设置初始位置
          // 设置到屏幕中间
          const kdCollectionPosition =
            series.yAxis.padding +
            (_container.clientWidth -
              series.yAxis.padding -
              series.yAxis.defaltPadding) /
              2;
          const kdCollectionPositionValue = _getRealXValueByXPixes(
            kdCollectionPosition,
            series
          );
          // //console.log("kdCollectionPositionValue:" +kdCollectionPositionValue)
          const collectonZoneWidth =
            (series.kdCollectionWidth /
              (series.xAxis.interval[1] - series.xAxis.interval[0])) *
            (_container.clientWidth -
              series.yAxis.padding -
              series.yAxis.defaltPadding);
          series.kdCollection = {
            type: "kdCollection",
            kdCollectionPosition: kdCollectionPosition,
            kdCollectionPositionValue: kdCollectionPositionValue,
            collectonZoneWidth: collectonZoneWidth,
            startX: kdCollectionPosition - collectonZoneWidth / 2,
            endX: kdCollectionPosition + collectonZoneWidth / 2,
            startY: series.xAxis.padding,
            endY: _container.clientHeight - series.xAxis.defaltPadding,
            points: [],
            words: [],
          };
        }
        if (
          !series.kdCollection.points ||
          series.kdCollection.points.length === 0
        ) {
          const points = [
            series.kdCollection.startX,
            series.kdCollection.startY,
            series.kdCollection.startX,
            series.kdCollection.endY,
            series.kdCollection.endX,
            series.kdCollection.endY,

            series.kdCollection.endX,
            series.kdCollection.endY,
            series.kdCollection.startX,
            series.kdCollection.startY,
            series.kdCollection.endX,
            series.kdCollection.startY,
          ];
          series.kdCollection.points = points;
          const s =
            "中心频率:" +
            (series.kdCollection.kdCollectionPositionValue / 1000000).toFixed(
              2
            ) +
            "MHz,带宽：" +
            series.kdCollectionWidth / 1000000 +
            "MHz";
          _textCtx.font = "13px sans-serif";
          series.kdCollectionword = {
            str: s,
            x:
              series.yAxis.padding +
              series.kdCollection.kdCollectionPosition -
              _textCtx.measureText(s).width / 2,
            y: _container.clientHeight / 2,
          };
        }

        _drawTransparentRect(series.kdCollection.points, _axisMatrix, {
          r: 0,
          g: 1,
          b: 1,
        });
        if (series.kdCollectionword) {
          _textCtx.fillStyle =
            "rgba(" +
            255 * series.measureTextColor.r +
            "," +
            255 * series.measureTextColor.g +
            "," +
            255 * series.measureTextColor.b +
            "," +
            255 * series.measureTextColor.a +
            ")";
          _textCtx.font = "13px sans-serif";
          _textCtx.fillText(
            series.kdCollectionword.str,
            series.kdCollectionword.x,
            series.kdCollectionword.y
          );
        }
      }
    });
  }

  /**
   * 绘制时间测量标记
   */
  function _drawTimeMeasure() {
    _Series.forEach((series) => {
      _gl.useProgram(_lineShaderProgram);
      _gl.viewport(0, 0, _gl.canvas.width, _gl.canvas.height);
      if (series.timeMeasureOpen && series.timeMeasure) {
        if (
          !series.timeMeasure.points ||
          series.timeMeasure.points.length === 0
        ) {
          const points = [
            series.timeMeasure.startX,
            series.timeMeasure.startY,
            series.timeMeasure.startX,
            series.timeMeasure.endY,
            series.timeMeasure.endX,
            series.timeMeasure.endY,

            series.timeMeasure.endX,
            series.timeMeasure.endY,
            series.timeMeasure.startX,
            series.timeMeasure.startY,
            series.timeMeasure.endX,
            series.timeMeasure.startY,
          ];
          series.timeMeasure.points = points;
        }
        _drawTransparentRect(series.timeMeasure.points, _axisMatrix, {
          r: 0,
          g: 1,
          b: 1,
        });
        if (
          !series.timeMeasure.words ||
          series.timeMeasure.words.length === 0
        ) {
          const realStartY = _getRealYValueByYPixes(
            series.timeMeasure.startY,
            series
          );
          const realEndY = _getRealYValueByYPixes(
            series.timeMeasure.endY,
            series
          );
          // 需要将realX转化成真实时间戳
          const startidx = series.yAxis.interval[1] - realStartY;
          const realstartYValue =
            series.yAxis.timeStamps[
              series.yAxis.timeStamps.length - 1 - Math.round(startidx)
            ];

          const endidx = series.yAxis.interval[1] - realEndY;
          const realEndYValue =
            series.yAxis.timeStamps[
              series.yAxis.timeStamps.length - 1 - Math.round(endidx)
            ];
          _textCtx.fillStyle = "rgba(0,255,255,0.5)";
          _textCtx.font = "15px sans-serif";
          series.timeMeasure.words = [
            {
              x:
                series.timeMeasure.startX -
                _textCtx.measureText(
                  getmmssSSS(realEndYValue - realstartYValue)
                ).width,
              y:
                _container.clientHeight -
                (series.timeMeasure.startY +
                  (series.timeMeasure.endY - series.timeMeasure.startY) / 2),
              // str: getmmssSSS(realEndYValue - realstartYValue).slice(-6) + 's'
              str: getmmssSSS(realEndYValue - realstartYValue),
            },
          ];
        }
        series.timeMeasure.words.forEach((word) => {
          _textCtx.fillStyle =
            "rgba(" +
            255 * series.measureTextColor.r +
            "," +
            255 * series.measureTextColor.g +
            "," +
            255 * series.measureTextColor.b +
            "," +
            255 * series.measureTextColor.a +
            ")";
          _textCtx.font = "15px sans-serif";
          _textCtx.fillText(word.str, word.x, word.y);
        });
      }
    });
  }

  /**
   * 绘制鼠标点击标记
   */
  function _drawMouseClickMarkPoints() {
    // 设置使用的着色器和viewport
    _gl.useProgram(_lineShaderProgram);
    _gl.viewport(0, 0, _gl.canvas.width, _gl.canvas.height);
    if (!_axisMatrix) {
      // 计算矩阵
      // 根据分辨率直接生成矩阵
      let projectionMatrix = m3.projection(
        _gl.canvas.clientWidth,
        _gl.canvas.clientHeight
      );
      // 因为上面的方法生成的矩阵原点在左上方 需要原点在左下方,所以先沿y轴平移canvas高度(向上),在沿y轴翻转 (这样原点的坐标就在左下了)
      const translationMatrix = m3.translation(0, _gl.canvas.clientHeight);
      projectionMatrix = m3.multiply(projectionMatrix, translationMatrix);
      // scaling 绕原点翻转(-1 ~ 1)
      projectionMatrix = m3.multiply(projectionMatrix, m3.scaling(1, -1));
      _axisMatrix = projectionMatrix;
    }
    _Series.forEach((series, index) => {
      // 设置使用的着色器和viewport
      if (
        series.mouseClickMarkPoints &&
        series.mouseClickMarkPoints.length > 0
      ) {
        // 暂时不需要绘制绿色点击的条了
        _drawLineGroup(series.mouseClickMarkPoints, _axisMatrix, {
          r: 255 / 255,
          g: 255 / 255,
          b: 255 / 255,
        });
        // 绘制文字
        if (series.mouseClickMarkWords) {
          series.mouseClickMarkWords.forEach((word) => {
            _textCtx.fillStyle = "rgba(255,255,255,1)";
            _textCtx.font = "15px sans-serif";
            _textCtx.fillText(word.str, word.x, word.y);
          });
        }
      }
    });
  }

  /**
   * 清空所有计算过的点坐标数据(需要重新计算)
   */
  function _clearCaculatedData() {
    _Series.forEach((series) => {
      // xAxis 重新计算
      series.xAxis.points = [];
      // yAxis 重新计算
      series.yAxis.points = [];
      // 表格线清空
      series.yTablePoints = [];
      series.xTablePoints = [];

      series.xAxis.markZonePoints = [];
      series.xAxis.markZonePointColors = [];
      series.xAxis.markZoneLRPoints = [];
      series.xAxis.markZoneLRPointsColors = [];

      series.xAxis.markZonesOfBlackListPoints = [];
      series.xAxis.markZonesOfBlackListPointColors = [];
      series.xAxis.markZonesOfBlackListLRPoints = [];
      series.xAxis.markZonesOfBlackListLRPointsColors = [];

      // 重新计算宽带采集图像坐标
      // series.kdCollection = null
      // 重新计算绘制折线的变换矩阵
      series._linesMatrix = null;
      series.lines.forEach((line) => {
        line.transferedData = [];
      });
      series.xAxis.markLines.forEach((markLine) => {
        markLine.points = [];
      });
      series.yAxis.markLines.forEach((markLine) => {
        markLine.points = [];
      });
      series.xAxis.markZones.forEach((markZone) => {
        markZone.points = [];
      });
      series.xAxis.markZonesOfBlackList.forEach((markZone) => {
        markZone.points = [];
      });
      series.xAxis.markZonesHighLight.forEach((markZoneHighLight) => {
        markZoneHighLight.points = [];
      });

      if (_config.type === "pubu") {
        series._projectionMatrix = null;
        _imageList.forEach((image) => {
          image._rectinfo = null;
        });
        series.rectMarkZonepoints = [];
        // series.rectMarkZone.forEach((markZone) => {
        //   // markZone.transformedData = []
        // })
      }

      series.centerDashLinePoints = null;

      // 清空鼠标测量的文字
      if(series.mouseStrapMeasure){
        series.mouseStrapMeasure.words = []
      }
    });
  }

  /**
   * 绘制图案的矩形的坐标生成
   */
  function _setRectangle(gl, x, y, width, height) {
    const x1 = x;
    const x2 = x + width;
    const y1 = y;
    const y2 = y + height;
    // _createBuffer([
    //   0.0, 0.0,
    //   1.0, 0.0,
    //   0.0, 1.0,
    //   0.0, 1.0,
    //   1.0, 0.0,
    //   1.0, 1.0
    // ])
    // (0,0)<------------(0,1)
    //   |               x/^
    //   |              // |
    //   |             //  |
    //   |            //   |
    //   |           //    |
    //   |          //     |
    //   |         //      |
    //   |        //       |
    //   |       //        |
    //   |      //         |
    //   |     //          |
    //   |    //           |
    //   |   //            |
    //   x  x              |
    // (1,0)------------->(1,1)
    _createBuffer([
      x1,
      y1, // 0,0,
      x2,
      y1, // 1,0
      x1,
      y2, // 0,1
      x1,
      y2, // 0,1
      x2,
      y1, // 1,0
      x2,
      y2, // 1,1
    ]);
    // 向上
    // _createBuffer([
    //   x1,y2,// 0,1
    //   x2,y2,// 1,1
    //   x1,y1,// 0,0,

    //   x1, y1, // 0,1
    //   x2, y1, // 1,0
    //   x2, y2,  // 1,0
    // ])
    // gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    //   x1, y1, // 0,0,
    //   x2, y1, // 1,0
    //   x1, y2, // 0,1
    //   x1, y2, // 0,1
    //   x2, y1, // 1,0
    //   x2, y2  // 1,1
    // ]), gl.STATIC_DRAW)
  }

  /**
   * 添加罗盘鼠标事件监听
   */
  function _addCompassMouseEventListener() {
    _textcontainer.onmousedown = (event) => {
      const x = event.offsetX - _container.clientWidth / 2;
      const y = -event.offsetY + _container.clientHeight / 2;
      _isMouseDown = true;
      _mouseDownStart = {
        x: x,
        y: y,
      };
    };
    _textcontainer.onmouseleave = (event) => {
      // //console.log('onmouseleave')
      if (_isMouseDown) {
        _isMouseDown = false;
        _compassConfig.preJiaotdu = null;
        // _isClickCompassPoint = false

        _compassConfig.totalJiaoDuChange = 0;
        // let change = (_compassPointRotation - _compassPointOldRotation) * 180 / Math.PI
        _compassConfig.compassPointRotation =
          _compassConfig.compassPointOldRotation;
        _compassConfig.sectorPoints = [];
        _refresh();
      }
    };
    _textcontainer.onmousemove = (event) => {
      const x = event.offsetX - _container.clientWidth / 2;
      const y = -event.offsetY + _container.clientHeight / 2;
      // 判断是否点击到了指针位置
      // if (!_isClickCompassPoint) {
      //   if (_isCursorInCompassPoints(x, y)) {
      //     _textcontainer.style.cursor = 'all-scroll'
      //   } else {
      //     _textcontainer.style.cursor = ''
      //   }
      //   return
      // }
      if (_isMouseDown) {
        const jiaodutmp = Math.atan2(x, y);
        let jiaodu = jiaodutmp;
        if (jiaodutmp < 0) {
          jiaodu = 2 * Math.PI + jiaodu;
        }
        // //console.log(jiaodu)
        const pointRotationLast = jiaodu;
        // 计算和之前角度的角度差值
        let jiaoduChange = 0;
        if (_compassConfig.preJiaotdu != null) {
          jiaoduChange = jiaodu - _compassConfig.preJiaotdu;
          // //console.log("preJiaotdu" +  _compassConfig.preJiaotdu)
          // //console.log("jiaoduChange" + jiaoduChange)
          if (Math.abs(jiaoduChange) > Math.PI) {
            // 可能是经过了y轴
            if (_compassConfig.preJiaotdu > jiaodu) {
              // //console.log("从左到右")
              // 从左到右
              jiaoduChange = 2 * Math.PI - _compassConfig.preJiaotdu + jiaodu;
            } else {
              // //console.log("从右到左")
              // 从右到左
              jiaoduChange = -(
                2 * Math.PI -
                jiaodu +
                _compassConfig.preJiaotdu
              );
            }
          }
          // if (Math.abs(jiaoduChange * 180 / Math.PI) > 100) {
          //   //console.log('jiaoduChange:' + (jiaoduChange * 180 / Math.PI))
          // }
          // //console.log('jiaoduChange:' + (jiaoduChange * 180 / Math.PI))
          _compassConfig.preJiaotdu = jiaodu;
        } else {
          // debugger
          jiaoduChange =
            jiaodu - getRotationByPoints(_mouseDownStart.x, _mouseDownStart.y);
          if (Math.abs(jiaoduChange) > Math.PI) {
            // 可能是经过了y轴 此时没有上一次所在的角度 直接比较点击开始位置的坐标x和当前坐标x的大小
            if (x > _mouseDownStart.x) {
              // //console.log("1从左到右")
              // 从左到右
              jiaoduChange =
                2 * Math.PI -
                getRotationByPoints(_mouseDownStart.x, _mouseDownStart.y) +
                jiaodu;
            } else {
              // //console.log("1从右到左")
              // 从右到左
              jiaoduChange = -(
                2 * Math.PI -
                jiaodu +
                getRotationByPoints(_mouseDownStart.x, _mouseDownStart.y)
              );
            }
          }
          _compassConfig.preJiaotdu = jiaodu;
        }
        _compassConfig.totalJiaoDuChange += jiaoduChange;

        if (Math.abs(_compassConfig.totalJiaoDuChange) > 2 * Math.PI) {
          if (_compassConfig.totalJiaoDuChange > 0) {
            _compassConfig.totalJiaoDuChange = 2 * Math.PI;
          } else {
            _compassConfig.totalJiaoDuChange = -2 * Math.PI;
          }
        }
        // //console.log("totalJiaoDuChange:" +_compassConfig.totalJiaoDuChange )
        // 绘制扇形区域
        const startRotation = getRotationByPoints(
          _mouseDownStart.x,
          _mouseDownStart.y
        );

        _compassConfig.startRotation = startRotation;
        // let stopRotation = startRotation + _compassConfig.totalJiaoDuChange
        const stopRotation = getRotationByPoints(x, y);
        _compassConfig.stopRotation = stopRotation;
        _compassConfig.pointShowJiaoDuChange = _compassConfig.totalJiaoDuChange;
        let points = [];
        points = points.concat([0, 0]);
        let n =
          Math.abs(
            ((_compassConfig.totalJiaoDuChange * 180) / Math.PI / 10).toFixed(0)
          ) * 5;
        if (n === 0) {
          n = 10;
        }
        const banjing = _container.clientHeight / 2 - 5;
        const startTheta = startRotation;
        for (let i = 0; i < n + 1; i++) {
          const theta = startTheta + (i * _compassConfig.totalJiaoDuChange) / n;
          const x1 = 0 + banjing * Math.sin(theta);
          const y1 = 0 + banjing * Math.cos(theta);
          points = points.concat([x1, y1]);
        }
        _compassConfig.sectorPoints = points;

        _refresh();
        // _drawTransparentTrangleFan([0, 0, 0, 150, 1, 140], _compassPointMatrix, {r: 1, g: 1, b: 1})
      }
    };
    _textcontainer.onmouseup = (event) => {
      if (_isMouseDown) {
        _isMouseDown = false;
        _compassConfig.preJiaotdu = null;
        // _isClickCompassPoint = false
        // //console.log(_compassConfig.totalJiaoDuChange * 180 / Math.PI)
        if (_compassConfig.compassMeasureListener) {
          _compassConfig.compassMeasureListener(
            (_compassConfig.totalJiaoDuChange * 180) / Math.PI
          );
        }
        _compassConfig.totalJiaoDuChange = 0;
        // let change = (_compassPointRotation - _compassPointOldRotation) * 180 / Math.PI
        _compassConfig.compassPointRotation =
          _compassConfig.compassPointOldRotation;
        _compassConfig.sectorPoints = [];

        _compassConfig.comapssShowPoints = [];
        _compassConfig.compassShowPointSizes = [];
        _refresh();
      }
    };
  }

  /**
   * 根据xy坐标计算角度(0~2π)
   */
  function getRotationByPoints(x, y) {
    let jiaodutmp = Math.atan2(x, y);
    if (jiaodutmp < 0) {
      jiaodutmp = 2 * Math.PI + jiaodutmp;
    }
    return jiaodutmp;
  }

  /**
   * 判断鼠标指针是否在罗盘指针上
   */
  function _isCursorInCompassPoints(x, y) {
    const points = [
      { x: _container.clientHeight / 60, y: _container.clientHeight / 2 - 10 },
      { x: -_container.clientHeight / 60, y: _container.clientHeight / 2 - 10 },

      { x: _container.clientHeight / 60, y: _container.clientHeight / 60 },
      { x: 0, y: -_container.clientHeight / 60 },
      { x: -_container.clientHeight / 60, y: _container.clientHeight / 60 },
      { x: 0, y: _container.clientHeight / 2 - 10 },
    ];
    // 所有的点需要旋转当前的指针的角度
    const matrix = m3.rotation(_compassConfig.compassPointRotation, []);
    const transformedPoints = [];
    for (let i = 0; i < points.length; i++) {
      const point = points[i];
      const tmp = m3.transformPoint(matrix, [point.x, point.y]);
      transformedPoints.push({
        x: tmp[0],
        y: tmp[1],
      });
    }
    const isIn = _pointInPolygon({ x, y }, transformedPoints, 5);
    return isIn;
  }

  /**
   * 判断点是否在多边形内部
   * 注意到如果从P作水平向左的射线的话，如果P在多边形内部，那么这条射线与多边形的交点必为奇数，如果P在多边形外部，则交点个数必为偶数（0也在内）。所以，我们可以顺序考虑多边形的每条边，求出交点的总个数。还有一些特殊情况要考虑。假如考虑边(P1,P2)，
   *   1)如果射线正好穿过P1或者P2,那么这个交点会被算作2次，处理办法是如果P的从坐标与P1,P2中较小的纵坐标相同，则直接忽略这种情况
   *   2)如果射线水平，则射线要么与其无交点，要么有无数个，这种情况也直接忽略。
   *   3)如果射线竖直，而P0的横坐标小于P1,P2的横坐标，则必然相交。
   *   4)再判断相交之前，先判断P是否在边(P1,P2)的上面，如果在，则直接得出结论：P再多边形内部。
   * 求解通过该点的水平线与多边形各边的交点
   * 单边交点为奇数，成立
   */
  function _pointInPolygon(point, ptPolygon, nCount) {
    let nCross = 0;
    for (let i = 0; i < nCount; i++) {
      const p1 = ptPolygon[i];
      const p2 = ptPolygon[(i + 1) % nCount];
      // 求解 y=p.y 与 p1p2 的交点
      if (p1.y === p2.y) {
        continue;
      }
      if (point.y < Math.min(p1.y, p2.y)) {
        continue;
      }
      if (point.y >= Math.max(p1.y, p2.y)) {
        continue;
      }
      // 求交点的 X 坐标 --------------------------------------------------------------
      const x = ((point.y - p1.y) * (p2.x - p1.x)) / (p2.y - p1.y) + p1.x;
      if (x > point.x) {
        nCross++;
      }
    }
    // 单边交点为偶数，点在多边形之外 ---
    return nCross % 2 === 1;
  }

  /**
   * 添加鼠标事件监听
   */
  function _addMouseEventListener() {
    _textcontainer.onmouseleave = (event) => {
      _isMouseDown = false;
      _mouseDownStart = {};
      _lastMousePosition = null;
      _mouseMovePre = null;
      // 清空拉出来的矩形
      _Series.forEach((series) => {
        series.mouseStrapPoints = [];
      });

      if (_isClickXaxisPadding) {
        _isClickXaxisPadding = false;
        // 调用onchange
        // if (_clickedXaxisSeries.xAxis.onXIntervalChange) {
        //   _clickedXaxisSeries.xAxis.onXIntervalChange([_clickedXaxisSeries.xAxis.interval[0], _clickedXaxisSeries.xAxis.interval[1]])
        // }
      }

      _Series.forEach((series) => {
        if (series.onMouseLeaveListener) {
          series.onMouseLeaveListener(event);
        }
      });
      _refresh();
    };
    _textcontainer.onmousewheel = (event) => {
      event.stopPropagation();
      event.preventDefault();
      if (!_isMouseDown) {
        // 缩放图表
        const x = event.offsetX;
        const y = event.offsetY;
        _Series.forEach((series, index) => {
          if (!series.allowZoom) {
            // 禁止了缩放
            return;
          }
          // 判断滚动区域是否在Axies图表内部
          // if (x < series.yAxis.padding) {
          //   return
          // }
          // if (x > (_container.clientWidth - series.yAxis.defaltPadding)) {
          //   return
          // }
          if (
            x <= _container.clientWidth - series.yAxis.defaltPadding &&
            x >= series.yAxis.padding
          ) {
            if (event.deltaY < 0) {
              // 往上方滚动 放大
              if (series.xAxis.minXInterval) {
                if (
                  series.xAxis.interval[1] - series.xAxis.interval[0] <=
                  series.xAxis.minXInterval
                ) {
                  // 已经到达最小间隔
                  return;
                }
              }
              const realX = _getRealXValueByXPixes(x, series);
              // 鼠标左右分别变成以前的 90%
              let nextLeft = realX - (realX - series.xAxis.interval[0]) * 0.9;
              let nextRight = realX + (series.xAxis.interval[1] - realX) * 0.9;
              if (series.xAxis.minXInterval) {
                // 判断改变过后的x最大值和最小值的间隔是否小于最小x间隔
                if (nextRight - nextLeft < series.xAxis.minXInterval) {
                  nextRight = nextLeft + series.xAxis.minXInterval;
                  if (nextRight > series.xAxis.oldInterval[1]) {
                    nextRight = series.xAxis.oldInterval[1];
                    nextLeft = nextRight - series.xAxis.minXInterval;
                  }
                }
              }
              // 重新设置
              series.xAxis.interval[0] = nextLeft;
              series.xAxis.interval[1] = nextRight;
              _clearCaculatedData();
              _refresh();
              // 调用onchange
              // if (series.xAxis.onXIntervalChange) {
              _doOnXIntervalChange(series, [nextLeft, nextRight]);
              // }
            }
            if (event.deltaY > 0) {
              // 往下方滚动 缩小
              const realX = _getRealXValueByXPixes(x, series);
              let newLeft = realX - (realX - series.xAxis.interval[0]) * 1.1;
              let newRight = realX + (series.xAxis.interval[1] - realX) * 1.1;
              if (newLeft < series.xAxis.oldInterval[0]) {
                newLeft = series.xAxis.oldInterval[0];
              }
              if (newRight > series.xAxis.oldInterval[1]) {
                newRight = series.xAxis.oldInterval[1];
              }
              series.xAxis.interval[0] = newLeft;
              series.xAxis.interval[1] = newRight;
              _clearCaculatedData();
              _refresh();
              // 调用onchange
              // if (series.xAxis.onXIntervalChange) {
              _doOnXIntervalChange(series, [newLeft, newRight]);
              // }
            }
          }
          // if (_config.type !== 'line') {
          //     // 只有线图才能放大y轴
          //     return
          // }
          if (
            y <= _container.clientHeight - series.xAxis.padding &&
            y >= series.xAxis.defaltPadding
          ) {
            if (
              x < series.yAxis.padding ||
              series.zoomYAxisInMouseWheelOnSerires
            ) {
              if (event.deltaY < 0) {
                // 往上方滚动 放大
                if (series.yAxis.minXInterval) {
                  if (
                    series.yAxis.interval[1] - series.yAxis.interval[0] <=
                    series.yAxis.minXInterval
                  ) {
                    // 已经到达最小间隔
                    return;
                  }
                }
                const realY = _getRealYValueByYPixes(
                  _container.clientHeight - y,
                  series
                );
                // 鼠标左右分别变成以前的 90%
                let nextLeft = realY - (realY - series.yAxis.interval[0]) * 0.9;
                let nextRight =
                  realY + (series.yAxis.interval[1] - realY) * 0.9;
                if (series.yAxis.minXInterval) {
                  // 判断改变过后的x最大值和最小值的间隔是否小于最小x间隔
                  if (nextRight - nextLeft < series.yAxis.minXInterval) {
                    nextRight = nextLeft + series.yAxis.minXInterval;
                    if (nextRight > series.yAxis.oldInterval[1]) {
                      nextRight = series.yAxis.oldInterval[1];
                      nextLeft = nextRight - series.yAxis.minXInterval;
                    }
                  }
                }
                // 重新设置
                series.yAxis.interval[0] = nextLeft;
                series.yAxis.interval[1] = nextRight;
                // if (true) {
                //   // 根据范围内的y轴数值动态修改y轴的interval
                //   autoResize(series)
                // }
                _clearCaculatedData();
                _refresh();
                // 调用onchange
                if (series.yAxis.onYIntervalChange) {
                  series.yAxis.onYIntervalChange([nextLeft, nextRight]);
                }
              }
              if (event.deltaY > 0) {
                // 往下方滚动 缩小
                const realY = _getRealYValueByYPixes(
                  _container.clientHeight - y,
                  series
                );
                let newLeft = realY - (realY - series.yAxis.interval[0]) * 1.1;
                let newRight = realY + (series.yAxis.interval[1] - realY) * 1.1;
                if (newLeft < series.yAxis.oldInterval[0]) {
                  newLeft = series.yAxis.oldInterval[0];
                }
                if (newRight > series.yAxis.oldInterval[1]) {
                  newRight = series.yAxis.oldInterval[1];
                }
                series.yAxis.interval[0] = newLeft;
                series.yAxis.interval[1] = newRight;
                // if (true) {
                //   // 根据范围内的y轴数值动态修改y轴的interval
                //   autoResize(series)
                // }
                _clearCaculatedData();
                _refresh();
                // 调用onchange
                if (series.yAxis.onYIntervalChange) {
                  series.yAxis.onYIntervalChange([newLeft, newRight]);
                }
              }
            }
          }
        });
      }
    };
    _textcontainer.onmousedown = (event) => {
      event.preventDefault();
      const x = event.offsetX;
      const y = event.offsetY;
      _isMouseDown = true;
      _mouseDownStart = event;
      _lastMousePosition = event;
      _mouseMovePre = {
        x: event.offsetX,
        y: event.offsetY,
      };
    };
    _textcontainer.onmouseup = (event) => {
      _isMouseDown = false;
      if (_isClickMarkLine) {
        // //console.log('之前拖动的是markline')
        // 之前拖动的是markline
        _isClickMarkLine = false;
        _clickedMarkLine = null;
        _clickedMarkLineSeries = null;
        const x = event.offsetX;
        const y = event.offsetY;
        const markFindResult = _findNearestMarkLine(x, y);
        if (markFindResult) {
          if (markFindResult.markLine.type === "x") {
            _textcontainer.style.cursor = "ew-resize";
          }
          if (markFindResult.markLine.type === "y") {
            _textcontainer.style.cursor = "ns-resize";
          }
          _isClickMarkLine = true;
          _clickedMarkLine = markFindResult.markLine;
          _clickedMarkLineSeries = markFindResult.series;

          if (markFindResult.markLine.onMouseUpListener) {
            markFindResult.markLine.onMouseUpListener(
              markFindResult.markLine.value
            );
          }
        } else {
          _textcontainer.style.cursor = "";
        }
      } else if (_isClickMeasureZone) {
        // 拖动的是x测量区域
        _isClickMeasureZone = false;
        _clickedMeasureZone = null;
        _clickedMeasureZoneSeries = null;
      } else if (_isClickToDragMeasureZone) {
        _isClickToDragMeasureZone = false;
        _clickedToDragMeasureZone = null;
      } else if (_isClickXaxisPadding) {
        _isClickXaxisPadding = false;
        // 调用onchange
        // if (_clickedXaxisSeries.xAxis.onXIntervalChange) {
        //   _clickedXaxisSeries.xAxis.onXIntervalChange([_clickedXaxisSeries.xAxis.interval[0], _clickedXaxisSeries.xAxis.interval[1]])
        // }
      } else if (_isClickMouseStrapMeasure) {
        // 点击鼠标拖动框内时啥也不干
      } else {
        // 拖动距离过小 认为是click
        if (
          Math.abs(_mouseDownStart.offsetX - event.offsetX) < 20 &&
          Math.abs(_mouseDownStart.offsetY - event.offsetY) < 20
        ) {
          const startPoint = {
            x: _mouseDownStart.offsetX,
            y: _mouseDownStart.offsetY,
          };
          const endPoint = {
            x: event.offsetX,
            y: event.offsetY,
          };

          // 绘制鼠标点击标记
          if (_config.type === "line") {
            _Series.forEach((series) => {
              // 不能越过边界
              if (startPoint.x < series.yAxis.padding) {
                startPoint.x = series.yAxis.padding;
              }
              if (
                startPoint.x >
                _container.clientWidth - series.yAxis.defaltPadding
              ) {
                startPoint.x =
                  _container.clientWidth - series.yAxis.defaltPadding;
              }
              if (startPoint.y < series.xAxis.defaltPadding) {
                startPoint.y = series.xAxis.defaltPadding;
              }
              if (
                startPoint.y >
                _container.clientHeight - series.xAxis.padding
              ) {
                startPoint.y = _container.clientHeight - series.xAxis.padding;
              }

              if (endPoint.x < series.yAxis.padding) {
                endPoint.x = series.yAxis.padding;
              }
              if (
                endPoint.x >
                _container.clientWidth - series.yAxis.defaltPadding
              ) {
                endPoint.x =
                  _container.clientWidth - series.yAxis.defaltPadding;
              }
              if (endPoint.y < series.xAxis.defaltPadding) {
                endPoint.y = series.xAxis.defaltPadding;
              }
              if (endPoint.y > _container.clientHeight - series.xAxis.padding) {
                endPoint.y = _container.clientHeight - series.xAxis.padding;
              }
              const startX = startPoint.x;
              const startY = _container.clientHeight - startPoint.y;

              const endX = endPoint.x;
              const endY = _container.clientHeight - endPoint.y;

              // if (_Series.length > 1) {
              // 在有多个series的情况下
              // 判断开始点是否在series内
              // 起点不在本series内的不算
              if (
                startPoint.x < series.yAxis.padding ||
                startPoint.x >
                  _container.clientWidth - series.yAxis.defaltPadding ||
                _container.clientHeight - startPoint.y < series.xAxis.padding ||
                _container.clientHeight - startPoint.y >
                  _container.clientHeight - series.xAxis.defaltPadding
              ) {
                return;
              }
              // }
              const mouseClickMarkPoints = [
                series.yAxis.padding,
                endY,
                _container.clientWidth - series.yAxis.defaltPadding,
                endY,
                endX,
                series.xAxis.padding,
                endX,
                _container.clientHeight - series.xAxis.defaltPadding,
              ];
              series.mouseClickMarkPoints = mouseClickMarkPoints;
            });
          } else if (_config.type === "pubu") {
          }
          _doOnclick(event);
          // 清空拉出来的矩形
          _Series.forEach((series) => {
            series.mouseStrapMeasure = null
            series.mouseStrapPoints = [];
          });
          _refresh();
        } else {
          if (event.button == 0) {
            // 左键拖动
          } else if (event.button == 2) {
            event.preventDefault();
            // 右键拖动
            // 判断是朝左拉动还是朝右拉动
            // 拉动结束
            const startPoint = {
              x: _mouseDownStart.offsetX,
              y: _mouseDownStart.offsetY,
            };
            const endPoint = {
              x: event.offsetX,
              y: event.offsetY,
            };
            _isClickXaxisPadding = false;
            // 清空拉出来的矩形
            _Series.forEach((series) => {
              series.mouseStrapPoints = [];
            });
            _Series.forEach((series) => {
              // console.log(series.dragType)
              if (series.dragType === "zoom") {
                if (!series.allowZoom) {
                  // 禁止了缩放
                  return;
                }
                // 处理拉动之后的操作
                if (startPoint.x < endPoint.x) {
                  // 向右拉动
                  let startX = startPoint.x;
                  const startY = startPoint.y;

                  let endX = endPoint.x;
                  const endY = endPoint.y;
                  // if (_Series.length > 1) {
                  // 在有多个series的情况下
                  // 判断开始点是否在series内
                  // 起点不在本series内的不算
                  if (
                    startPoint.x < series.yAxis.padding ||
                    startPoint.x >
                      _container.clientWidth - series.yAxis.defaltPadding ||
                    _container.clientHeight - startPoint.y <
                      series.xAxis.padding ||
                    _container.clientHeight - startPoint.y >
                      _container.clientHeight - series.xAxis.defaltPadding
                  ) {
                    return;
                  }
                  // }
                  // 如果当前已经到了最小间隔,则不继续处理
                  if (series.xAxis.minXInterval) {
                    if (
                      series.xAxis.interval[1] - series.xAxis.interval[0] <=
                      series.xAxis.minXInterval
                    ) {
                      _clearCaculatedData();
                      _refresh();
                      return;
                    }
                  }
                  if (startX < series.yAxis.padding) {
                    startX = series.yAxis.padding;
                  }
                  if (
                    startX >
                    _container.clientWidth - series.yAxis.defaltPadding
                  ) {
                    startX =
                      _container.clientWidth - series.yAxis.defaltPadding;
                  }
                  if (endX < series.yAxis.padding) {
                    endX = series.yAxis.padding;
                  }
                  if (
                    endX >
                    _container.clientWidth - series.yAxis.defaltPadding
                  ) {
                    endX = _container.clientWidth - series.yAxis.defaltPadding;
                  }

                  // 计算开始点和结束点的对应x值
                  let realStartX = _getRealXValueByXPixes(startX, series);
                  let realEndX = _getRealXValueByXPixes(endX, series);

                  if (series.xAxis.minXInterval) {
                    // 判断改变过后的x最大值和最小值的间隔是否小于最小x间隔
                    if (realEndX - realStartX < series.xAxis.minXInterval) {
                      realEndX = realStartX + series.xAxis.minXInterval;
                      if (realEndX > series.xAxis.oldInterval[1]) {
                        realEndX = series.xAxis.oldInterval[1];
                        realStartX = realEndX - series.xAxis.minXInterval;
                      }
                    }
                  }
                  // 设置 x轴左右间隔 刷新
                  series.xAxis.interval[0] = realStartX;
                  series.xAxis.interval[1] = realEndX;
                  _clearCaculatedData();
                  _refresh();
                  // if (series.xAxis.onXIntervalChange) {
                  _doOnXIntervalChange(series, [realStartX, realEndX]);
                  // }
                } else {
                  // 向左拉动
                  let startX = startPoint.x;
                  const startY = startPoint.y;

                  let endX = endPoint.x;
                  const endY = endPoint.y;

                  // if (_Series.length > 1) {
                  // 在有多个series的情况下
                  // 判断开始点是否在series内
                  // 起点不在本series内的不算
                  if (
                    startPoint.x < series.yAxis.padding ||
                    startPoint.x >
                      _container.clientWidth - series.yAxis.defaltPadding ||
                    _container.clientHeight - startPoint.y <
                      series.xAxis.padding ||
                    _container.clientHeight - startPoint.y >
                      _container.clientHeight - series.xAxis.defaltPadding
                  ) {
                    return;
                  }
                  // }
                  if (startX < series.yAxis.padding) {
                    startX = series.yAxis.padding;
                  }
                  if (
                    startX >
                    _container.clientWidth - series.yAxis.defaltPadding
                  ) {
                    startX =
                      _container.clientWidth - series.yAxis.defaltPadding;
                  }
                  if (endX < series.yAxis.padding) {
                    endX = series.yAxis.padding;
                  }
                  if (
                    endX >
                    _container.clientWidth - series.yAxis.defaltPadding
                  ) {
                    endX = _container.clientWidth - series.yAxis.defaltPadding;
                  }

                  // 恢复 x轴左右间隔 刷新
                  series.xAxis.interval[0] = series.xAxis.oldInterval[0];
                  series.xAxis.interval[1] = series.xAxis.oldInterval[1];

                  if (_config.type === "line") {
                    // console.log('左上画矩形:', series)
                    series.yAxis.interval[0] = series.yAxis.oldInterval[0];
                    series.yAxis.interval[1] = series.yAxis.oldInterval[1];
                  }

                  _clearCaculatedData();
                  _refresh();
                  // if (series.xAxis.onXIntervalChange) {
                  _doOnXIntervalChange(series, [
                    _Series[0].xAxis.oldInterval[0],
                    _Series[0].xAxis.oldInterval[1],
                  ]);
                  // }
                }
              }
              if (series.dragType === "measure") {
                _Series.forEach((series) => {
                  let startX = startPoint.x;
                  let startY = startPoint.y;

                  let endX = endPoint.x;
                  let endY = endPoint.y;

                  // if (_Series.length > 1) {
                  // 在有多个series的情况下
                  // 判断开始点是否在series内
                  // 起点不在本series内的不算
                  if (
                    startPoint.x < series.yAxis.padding ||
                    startPoint.x >
                      _container.clientWidth - series.yAxis.defaltPadding ||
                    _container.clientHeight - startPoint.y <
                      series.xAxis.padding ||
                    _container.clientHeight - startPoint.y >
                      _container.clientHeight - series.xAxis.defaltPadding
                  ) {
                    return;
                  }
                  // }
                  if (startX < series.yAxis.padding) {
                    startX = series.yAxis.padding;
                  }
                  if (
                    startX >
                    _container.clientWidth - series.yAxis.defaltPadding
                  ) {
                    startX =
                      _container.clientWidth - series.yAxis.defaltPadding;
                  }
                  if (endX < series.yAxis.padding) {
                    endX = series.yAxis.padding;
                  }
                  if (
                    endX >
                    _container.clientWidth - series.yAxis.defaltPadding
                  ) {
                    endX = _container.clientWidth - series.yAxis.defaltPadding;
                  }

                  if (startY < series.xAxis.padding) {
                    startY = series.xAxis.padding;
                  }
                  if (
                    startY >
                    _container.clientHeight - series.xAxis.defaltPadding
                  ) {
                    startY =
                      _container.clientHeight - series.xAxis.defaltPadding;
                  }
                  if (endY < series.xAxis.padding) {
                    endY = series.xAxis.padding;
                  }
                  if (
                    endY >
                    _container.clientHeight - series.xAxis.defaltPadding
                  ) {
                    endY = _container.clientHeight - series.xAxis.defaltPadding;
                  }
                  _refresh();
                  if (_config.type === "line") {
                    const realStartX = _getRealXValueByXPixes(startX, series);
                    const realStartY = _getRealYValueByYPixes(
                      _container.clientHeight - startY,
                      series
                    );

                    const realEndX = _getRealXValueByXPixes(endX, series);
                    const realEndY = _getRealYValueByYPixes(
                      _container.clientHeight - endY,
                      series
                    );

                    if (series.onMeasureListener) {
                      series.onMeasureListener(
                        realStartX,
                        realStartY,
                        realEndX,
                        realEndY
                      );
                    }
                  } else if (_config.type === "pubu") {
                    if (series.yAxis.timeStamps.length === 0) {
                      return;
                    }
                    const realStartX = _getRealXValueByXPixes(startX, series);
                    const realStartY = _getRealYValueByYPixes(
                      _container.clientHeight - startY,
                      series
                    );

                    const realEndX = _getRealXValueByXPixes(endX, series);
                    const realEndY = _getRealYValueByYPixes(
                      _container.clientHeight - endY,
                      series
                    );
                    // 需要将realX转化成真实时间戳
                    const startidx = series.yAxis.interval[1] - realStartY;
                    const realYrealStartYValue =
                      series.yAxis.timeStamps[
                        series.yAxis.timeStamps.length -
                          1 -
                          Math.round(startidx)
                      ];

                    const endidx = series.yAxis.interval[1] - realEndY;
                    const realEndYValue =
                      series.yAxis.timeStamps[
                        series.yAxis.timeStamps.length - 1 - Math.round(endidx)
                      ];

                    if (series.onMeasureListener) {
                      series.onMeasureListener(
                        realStartX,
                        realYrealStartYValue,
                        realEndX,
                        realEndYValue
                      );
                    }
                    // 判断是否打开了timemeasure 绘制矩形
                    if (series.timeMeasureOpen) {
                      // 计算时间
                      series.timeMeasure = {
                        type: "time",
                        startX: startX,
                        endX: endX,
                        startY: _container.clientHeight - startY,
                        endY: _container.clientHeight - endY,
                        words: [
                          {
                            x:
                              startX -
                              _textCtx.measureText(
                                getHHmmssSSS(realYrealStartYValue)
                              ).width,
                            y: startY + 10,
                            str: getHHmmssSSS(realYrealStartYValue),
                          },
                          {
                            x:
                              startX -
                              _textCtx.measureText(getHHmmssSSS(realEndYValue))
                                .width,
                            y: endY,
                            str: getHHmmssSSS(realEndYValue),
                          },
                        ],
                      };
                    }
                    // let realX = _getRealXValueByXPixes(x, series)
                    // // y坐标从下往上递增
                    // let realY = _getRealYValueByYPixes(_container.clientHeight - y, series)
                    // // 查看鼠标是否移动到y轴mark上了
                    // //console.log(series)
                    // // 需要将realX转化成真实时间戳
                    // let idx = series.yAxis.interval[1] - realY
                    // let realYValue = series.yAxis.timeStamps[(series.yAxis.timeStamps.length - 1) - Math.round(idx)]

                    // if (series.onMouseMoveListener) {
                    //   series.onMouseMoveListener(realX, realYValue, event)
                    // }
                  }
                });
              }
            });
          } else if (event.button == 1) {
          }
        }
      }
      _mouseMovePre = null;
    };
    _textcontainer.onmousemove = (event) => {
        if (_isMouseDown) {
        // 鼠标点击拖动 绘制方框
        const startPoint = {
          x: _mouseDownStart.offsetX,
          y: _mouseDownStart.offsetY,
        };
        const endPoint = {
          x: event.offsetX,
          y: event.offsetY,
        };
        if (_isClickMarkLine) {
          // 拖动的是markline
          // 不能越过边界
          if (startPoint.x < _clickedMarkLineSeries.yAxis.padding) {
            startPoint.x = _clickedMarkLineSeries.yAxis.padding;
          }
          if (
            startPoint.x >
            _container.clientWidth - _clickedMarkLineSeries.yAxis.defaltPadding
          ) {
            startPoint.x =
              _container.clientWidth -
              _clickedMarkLineSeries.yAxis.defaltPadding;
          }
          if (startPoint.y < _clickedMarkLineSeries.xAxis.defaltPadding) {
            startPoint.y = _clickedMarkLineSeries.xAxis.defaltPadding;
          }
          if (
            startPoint.y >
            _container.clientHeight - _clickedMarkLineSeries.xAxis.padding
          ) {
            startPoint.y =
              _container.clientHeight - _clickedMarkLineSeries.xAxis.padding;
          }

          if (endPoint.x < _clickedMarkLineSeries.yAxis.padding) {
            endPoint.x = _clickedMarkLineSeries.yAxis.padding;
          }
          if (
            endPoint.x >
            _container.clientWidth - _clickedMarkLineSeries.yAxis.defaltPadding
          ) {
            endPoint.x =
              _container.clientWidth -
              _clickedMarkLineSeries.yAxis.defaltPadding;
          }
          if (endPoint.y < _clickedMarkLineSeries.xAxis.defaltPadding) {
            endPoint.y = _clickedMarkLineSeries.xAxis.defaltPadding;
          }
          if (
            endPoint.y >
            _container.clientHeight - _clickedMarkLineSeries.xAxis.padding
          ) {
            endPoint.y =
              _container.clientHeight - _clickedMarkLineSeries.xAxis.padding;
          }

          _clickedMarkLine.pixes = endPoint;
          if (_clickedMarkLine.type === "x") {
            const pixes = endPoint.x;
            const realXValue = _getRealXValueByXPixes(
              pixes,
              _clickedMarkLineSeries
            );
            _clickedMarkLine.pixes = pixes;
            _clickedMarkLine.value = realXValue;
            _clickedMarkLine.points = [];
            if (_clickedMarkLine.onValueChangeListener) {
              _clickedMarkLine.onValueChangeListener(realXValue);
            }
          }
          if (_clickedMarkLine.type === "y") {
            const pixes = _container.clientHeight - endPoint.y;
            const realYValue = _getRealYValueByYPixes(
              pixes,
              _clickedMarkLineSeries
            );
            _clickedMarkLine.pixes = pixes;
            _clickedMarkLine.value = realYValue;
            _clickedMarkLine.points = [];
            if (_clickedMarkLine.onValueChangeListener) {
              _clickedMarkLine.onValueChangeListener(realYValue);
            }
          }
        } else if (_isClickMeasureZone) {
          // console.log("!!!!!!!!!")
          // 拖动了测量区域
          // 不能越过边界
          if (startPoint.x < _clickedMeasureZone.series.yAxis.padding) {
            startPoint.x = _clickedMeasureZone.series.yAxis.padding;
          }
          if (
            startPoint.x >
            _container.clientWidth -
              _clickedMeasureZone.series.yAxis.defaltPadding
          ) {
            startPoint.x =
              _container.clientWidth -
              _clickedMeasureZone.series.yAxis.defaltPadding;
          }
          if (startPoint.y < _clickedMeasureZone.series.xAxis.defaltPadding) {
            startPoint.y = _clickedMeasureZone.series.xAxis.defaltPadding;
          }
          if (
            startPoint.y >
            _container.clientHeight - _clickedMeasureZone.series.xAxis.padding
          ) {
            startPoint.y =
              _container.clientHeight -
              _clickedMeasureZone.series.xAxis.padding;
          }

          if (endPoint.x < _clickedMeasureZone.series.yAxis.padding) {
            endPoint.x = _clickedMeasureZone.series.yAxis.padding;
          }
          if (
            endPoint.x >
            _container.clientWidth -
              _clickedMeasureZone.series.yAxis.defaltPadding
          ) {
            endPoint.x =
              _container.clientWidth -
              _clickedMeasureZone.series.yAxis.defaltPadding;
          }
          if (endPoint.y < _clickedMeasureZone.series.xAxis.defaltPadding) {
            endPoint.y = _clickedMeasureZone.series.xAxis.defaltPadding;
          }
          if (
            endPoint.y >
            _container.clientHeight - _clickedMeasureZone.series.xAxis.padding
          ) {
            endPoint.y =
              _container.clientHeight -
              _clickedMeasureZone.series.xAxis.padding;
          }

          if (_clickedMeasureZone.direction === "left") {
            let xPixes = endPoint.x;
            // 左边不能拖动到比右边还右边
            if(xPixes > _clickedMeasureZone.measureZone.endX ){
              xPixes = _clickedMeasureZone.measureZone.startX
            }
            if (_clickedMeasureZone.measureZone.type === "SNR") {
              _clickedMeasureZone.measureZone.startX = xPixes;
              _clickedMeasureZone.series.SNRMeasure.points = [];
              _clickedMeasureZone.measureZone.words = [];
            } else if(_clickedMeasureZone.measureZone.type === "freq") {
              _clickedMeasureZone.measureZone.startX = xPixes;
              _clickedMeasureZone.series.freqMeasure.points = [];
              _clickedMeasureZone.measureZone.words = [];
            }
          } else if (_clickedMeasureZone.direction === "left-top") {
            let xPixes = endPoint.x;
            // 左边不能拖动到比右边还右边
            if(xPixes > _clickedMeasureZone.measureZone.endX ){
              xPixes = _clickedMeasureZone.measureZone.startX
            }
            let yPixes = _container.clientHeight - endPoint.y;
            // 顶边不能拖动到比底边还低
            if(yPixes < _clickedMeasureZone.measureZone.startY ){
              yPixes = _clickedMeasureZone.measureZone.endY
            }
            if (_clickedMeasureZone.measureZone.type === "SNR") {
              _clickedMeasureZone.measureZone.startX = xPixes;
              _clickedMeasureZone.measureZone.endY = yPixes;
              _clickedMeasureZone.series.SNRMeasure.points = [];
              _clickedMeasureZone.measureZone.words = [];
            }
          } else if (_clickedMeasureZone.direction === "left-bottom") {
            let xPixes = endPoint.x;
            // 左边不能拖动到比右边还右边
            if(xPixes > _clickedMeasureZone.measureZone.endX ){
              xPixes = _clickedMeasureZone.measureZone.startX
            }
            let yPixes = _container.clientHeight - endPoint.y;
            // 底边不能拖动到比顶边还高
            if(yPixes > _clickedMeasureZone.measureZone.endY ){
              yPixes = _clickedMeasureZone.measureZone.startY
            }
            if (_clickedMeasureZone.measureZone.type === "SNR") {
              _clickedMeasureZone.measureZone.startX = xPixes;
              _clickedMeasureZone.measureZone.startY = yPixes;
              _clickedMeasureZone.series.SNRMeasure.points = [];
              _clickedMeasureZone.measureZone.words = [];
            }
          } else if (_clickedMeasureZone.direction === "right") {
            let xPixes = endPoint.x;
            // 右边边不能拖动到比左边还左边
            if(xPixes < _clickedMeasureZone.measureZone.startX ){
              xPixes = _clickedMeasureZone.measureZone.endX
            }
            if (_clickedMeasureZone.measureZone.type === "SNR") {
              _clickedMeasureZone.measureZone.endX = xPixes;
              _clickedMeasureZone.series.SNRMeasure.points = [];
              _clickedMeasureZone.measureZone.words = [];
            } else if (_clickedMeasureZone.measureZone.type === "freq") {
              _clickedMeasureZone.measureZone.endX = xPixes;
              _clickedMeasureZone.series.freqMeasure.points = [];
              _clickedMeasureZone.measureZone.words = [];
            }
          } else if (_clickedMeasureZone.direction === "right-top") {
            let xPixes = endPoint.x;
            // 右边边不能拖动到比左边还左边
            if(xPixes < _clickedMeasureZone.measureZone.startX ){
              xPixes = _clickedMeasureZone.measureZone.endX
            }
            let yPixes = _container.clientHeight - endPoint.y;
            // 顶边不能拖动到比底边还低
            if(yPixes < _clickedMeasureZone.measureZone.startY ){
              yPixes = _clickedMeasureZone.measureZone.endY
            }
            if (_clickedMeasureZone.measureZone.type === "SNR") {
              _clickedMeasureZone.measureZone.endX = xPixes;
              _clickedMeasureZone.measureZone.endY = yPixes;
              _clickedMeasureZone.series.SNRMeasure.points = [];
              _clickedMeasureZone.measureZone.words = [];
            }
          } else if (_clickedMeasureZone.direction === "right-bottom") {
            let xPixes = endPoint.x;
            // 右边边不能拖动到比左边还左边
            if(xPixes < _clickedMeasureZone.measureZone.startX ){
              xPixes = _clickedMeasureZone.measureZone.endX
            }
            let yPixes = _container.clientHeight - endPoint.y;
            // 底边不能拖动到比顶边还高
            if(yPixes > _clickedMeasureZone.measureZone.endY ){
              yPixes = _clickedMeasureZone.measureZone.startY
            }
            if (_clickedMeasureZone.measureZone.type === "SNR") {
              _clickedMeasureZone.measureZone.endX = xPixes;
              _clickedMeasureZone.measureZone.startY = yPixes;
              _clickedMeasureZone.series.SNRMeasure.points = [];
              _clickedMeasureZone.measureZone.words = [];
            }
          } else if (_clickedMeasureZone.direction === "bottom") {
            let yPixes = _container.clientHeight - endPoint.y;
            // 底边不能拖动到比顶边还高
            if(yPixes > _clickedMeasureZone.measureZone.endY ){
              yPixes = _clickedMeasureZone.measureZone.startY
            }
            if (_clickedMeasureZone.measureZone.type === "SNR") {
              _clickedMeasureZone.measureZone.startY = yPixes;
              _clickedMeasureZone.series.SNRMeasure.points = [];
              _clickedMeasureZone.measureZone.words = [];
            } else if (_clickedMeasureZone.measureZone.type === "time") {
              _clickedMeasureZone.measureZone.startY = yPixes;
              // 计算时间
              _clickedMeasureZone.measureZone.points = [];
              _clickedMeasureZone.measureZone.words = [];
            }
          } else if (_clickedMeasureZone.direction === "top") {
            let yPixes = _container.clientHeight - endPoint.y;
            // 顶边不能拖动到比底边还低
            if(yPixes < _clickedMeasureZone.measureZone.startY ){
              yPixes = _clickedMeasureZone.measureZone.endY
            }
            if (_clickedMeasureZone.measureZone.type === "SNR") {
              _clickedMeasureZone.measureZone.endY = yPixes;
              _clickedMeasureZone.series.SNRMeasure.points = [];
              _clickedMeasureZone.measureZone.words = [];
            } else if (_clickedMeasureZone.measureZone.type === "time") {
              _clickedMeasureZone.measureZone.endY = yPixes;

              // 计算时间
              _clickedMeasureZone.measureZone.points = [];
              _clickedMeasureZone.measureZone.words = [];
            }
          } else if (_clickedMeasureZone.direction === "all") {
            const xPixes = endPoint.x;
            if (_clickedMeasureZone.measureZone.type === "kdCollection") {
              const xMoveDistance = event.offsetX - _lastMousePosition.offsetX;
              // //console.log("xMoveDistance " + xMoveDistance)

              // //console.log("kdCollectionPosition " +  _clickedMeasureZone.measureZone.kdCollectionPosition)

              let newKdCollectionPosition =
                _clickedMeasureZone.measureZone.kdCollectionPosition +
                xMoveDistance;
              // //console.log("newKdCollectionPosition " + newKdCollectionPosition)

              // //console.log("kdCollectionPositionValue " + _clickedMeasureZone.measureZone.kdCollectionPositionValue)
              let newkdCollectionPositionValue = _getRealXValueByXPixes(
                newKdCollectionPosition,
                _clickedMeasureZone.series
              );

              // //console.log("newkdCollectionPositionValue " + newkdCollectionPositionValue)
              // debugger
              // 判断是否超出边界
              let startX =
                newKdCollectionPosition -
                _clickedMeasureZone.measureZone.collectonZoneWidth / 2;
              let endX =
                newKdCollectionPosition +
                _clickedMeasureZone.measureZone.collectonZoneWidth / 2;

              if (startX < _clickedMeasureZone.series.yAxis.padding) {
                startX = _clickedMeasureZone.series.yAxis.padding;
                endX =
                  startX + _clickedMeasureZone.measureZone.collectonZoneWidth;
                newKdCollectionPosition =
                  startX +
                  _clickedMeasureZone.measureZone.collectonZoneWidth / 2;
                newkdCollectionPositionValue = _getRealXValueByXPixes(
                  newKdCollectionPosition,
                  _clickedMeasureZone.series
                );
              }
              if (
                endX >
                _container.clientWidth -
                  _clickedMeasureZone.series.yAxis.defaltPadding
              ) {
                endX =
                  _container.clientWidth -
                  _clickedMeasureZone.series.yAxis.defaltPadding;
                startX =
                  endX - _clickedMeasureZone.measureZone.collectonZoneWidth;

                newKdCollectionPosition =
                  startX +
                  _clickedMeasureZone.measureZone.collectonZoneWidth / 2;
                newkdCollectionPositionValue = _getRealXValueByXPixes(
                  newKdCollectionPosition,
                  _clickedMeasureZone.series
                );
              }
              _clickedMeasureZone.measureZone.kdCollectionPosition =
                newKdCollectionPosition;
              _clickedMeasureZone.measureZone.kdCollectionPositionValue =
                newkdCollectionPositionValue;

              _clickedMeasureZone.measureZone.startX =
                newKdCollectionPosition -
                _clickedMeasureZone.measureZone.collectonZoneWidth / 2;
              _clickedMeasureZone.measureZone.endX =
                newKdCollectionPosition +
                _clickedMeasureZone.measureZone.collectonZoneWidth / 2;
              _clickedMeasureZone.measureZone.points = [];

              if (_clickedMeasureZone.series.kdCollectionListener) {
                _clickedMeasureZone.series.kdCollectionListener(
                  newkdCollectionPositionValue
                );
              }
              // //console.log("newkdCollectionPositionValue:" + newkdCollectionPositionValue / 1000000)
            }
            _lastMousePosition = event;
          }
        } else if (_isClickToDragMeasureZone) {
          // 拖动了测量区域内部
          // 计算出在x轴和y轴拖动的距离

          let yDragLength = 0;
          if (_mouseMovePre) {
            yDragLength =
              _container.clientHeight -
              endPoint.y -
              (_container.clientHeight - _mouseMovePre.y);
          } else {
            yDragLength =
              _container.clientHeight -
              endPoint.y -
              (_container.clientHeight - startPoint.y);
          }
          let xDragLength = 0;
          if (_mouseMovePre) {
            xDragLength = endPoint.x - _mouseMovePre.x;
          } else {
            xDragLength = endPoint.x - startPoint.x;
          }
          const xPixes = endPoint.x;
          if (_clickedToDragMeasureZone.measureZone.type === "freq") {
            if (
              _clickedToDragMeasureZone.measureZone.startX + xDragLength <
              _clickedToDragMeasureZone.series.yAxis.padding
            ) {
              xDragLength =
                _clickedToDragMeasureZone.measureZone.startX -
                _clickedToDragMeasureZone.series.yAxis.padding;
            }
            if (
              _clickedToDragMeasureZone.measureZone.endX + xDragLength >
              _container.clientWidth -
                _clickedToDragMeasureZone.series.yAxis.defaltPadding
            ) {
              xDragLength =
                _container.clientWidth -
                _clickedToDragMeasureZone.series.yAxis.defaltPadding -
                _clickedToDragMeasureZone.measureZone.endX;
            }
            _clickedToDragMeasureZone.measureZone.startX =
              _clickedToDragMeasureZone.measureZone.startX + xDragLength;
            _clickedToDragMeasureZone.measureZone.endX =
              _clickedToDragMeasureZone.measureZone.endX + xDragLength;
            _clickedToDragMeasureZone.series.freqMeasure.points = [];
            _clickedToDragMeasureZone.measureZone.words = [];
          }
          if (_clickedToDragMeasureZone.measureZone.type === "SNR") {
            if (
              _clickedToDragMeasureZone.measureZone.startX + xDragLength <
              _clickedToDragMeasureZone.series.yAxis.padding
            ) {
              xDragLength =
                _clickedToDragMeasureZone.measureZone.startX -
                _clickedToDragMeasureZone.series.yAxis.padding;
            }
            if (
              _clickedToDragMeasureZone.measureZone.endX + xDragLength >
              _container.clientWidth -
                _clickedToDragMeasureZone.series.yAxis.defaltPadding
            ) {
              xDragLength =
                _container.clientWidth -
                _clickedToDragMeasureZone.series.yAxis.defaltPadding -
                _clickedToDragMeasureZone.measureZone.endX;
            }

            if (
              _clickedToDragMeasureZone.measureZone.startY + yDragLength <
              _clickedToDragMeasureZone.series.xAxis.padding
            ) {
              yDragLength =
                _clickedToDragMeasureZone.measureZone.startY -
                _clickedToDragMeasureZone.series.xAxis.padding;
            }
            if (
              _clickedToDragMeasureZone.measureZone.endY + yDragLength >
              _container.clientHeight -
                _clickedToDragMeasureZone.series.xAxis.defaltPadding
            ) {
              yDragLength =
                _container.clientHeight -
                _clickedToDragMeasureZone.series.xAxis.defaltPadding -
                _clickedToDragMeasureZone.measureZone.endY;
            }
            _clickedToDragMeasureZone.measureZone.startX =
              _clickedToDragMeasureZone.measureZone.startX + xDragLength;
            _clickedToDragMeasureZone.measureZone.endX =
              _clickedToDragMeasureZone.measureZone.endX + xDragLength;
            _clickedToDragMeasureZone.measureZone.startY =
              _clickedToDragMeasureZone.measureZone.startY + yDragLength;
            _clickedToDragMeasureZone.measureZone.endY =
              _clickedToDragMeasureZone.measureZone.endY + yDragLength;

            _clickedToDragMeasureZone.series.SNRMeasure.points = [];
            _clickedToDragMeasureZone.measureZone.words = [];
          }

          if (_clickedToDragMeasureZone.measureZone.type === "time") {
            if (
              _clickedToDragMeasureZone.measureZone.startX + xDragLength <
              _clickedToDragMeasureZone.series.yAxis.padding
            ) {
              xDragLength =
                _clickedToDragMeasureZone.measureZone.startX -
                _clickedToDragMeasureZone.series.yAxis.padding;
            }
            if (
              _clickedToDragMeasureZone.measureZone.endX + xDragLength >
              _container.clientWidth -
                _clickedToDragMeasureZone.series.yAxis.defaltPadding
            ) {
              xDragLength =
                _container.clientWidth -
                _clickedToDragMeasureZone.series.yAxis.defaltPadding -
                _clickedToDragMeasureZone.measureZone.endX;
            }

            if (
              _clickedToDragMeasureZone.measureZone.startY + yDragLength <
              _clickedToDragMeasureZone.series.xAxis.padding
            ) {
              yDragLength =
                _clickedToDragMeasureZone.measureZone.startY -
                _clickedToDragMeasureZone.series.xAxis.padding;
            }
            if (
              _clickedToDragMeasureZone.measureZone.endY + yDragLength >
              _container.clientHeight -
                _clickedToDragMeasureZone.series.xAxis.defaltPadding
            ) {
              yDragLength =
                _container.clientHeight -
                _clickedToDragMeasureZone.series.xAxis.defaltPadding -
                _clickedToDragMeasureZone.measureZone.endY;
            }
            const startX =
              _clickedToDragMeasureZone.measureZone.startX + xDragLength;
            const endX =
              _clickedToDragMeasureZone.measureZone.endX + xDragLength;
            const startY =
              _clickedToDragMeasureZone.measureZone.startY + yDragLength;
            const endY =
              _clickedToDragMeasureZone.measureZone.endY + yDragLength;

            _clickedToDragMeasureZone.measureZone.points = [];
            _clickedToDragMeasureZone.measureZone.startX = startX;
            _clickedToDragMeasureZone.measureZone.endX = endX;
            _clickedToDragMeasureZone.measureZone.startY = startY;
            _clickedToDragMeasureZone.measureZone.endY = endY;
            _clickedToDragMeasureZone.measureZone.words = [];
          }
          _mouseMovePre = {
            x: event.offsetX,
            y: event.offsetY,
          };
        } else if (_isClickYaxisPadding) {
          // 向上拖动y轴
          // let realYvalue = _getRealYValueByYPixes()
          let dragLength = 0;
          if (_mouseMovePre) {
            dragLength =
              _container.clientHeight -
              endPoint.y -
              (_container.clientHeight - _mouseMovePre.y);
          } else {
            dragLength =
              _container.clientHeight -
              endPoint.y -
              (_container.clientHeight - startPoint.y);
          }
          const percent =
            dragLength /
            (_container.clientHeight -
              _clickedYaxisSeries.xAxis.padding -
              _clickedYaxisSeries.xAxis.defaltPadding);
          const dragValue =
            (_clickedYaxisSeries.yAxis.interval[1] -
              _clickedYaxisSeries.yAxis.interval[0]) *
            percent;
          // dragLength > 0 朝上 <0 朝下
          let startYValue = _clickedYaxisSeries.yAxis.interval[0] - dragValue;
          let endYValue = _clickedYaxisSeries.yAxis.interval[1] - dragValue;
          if (startYValue <= _clickedYaxisSeries.yAxis.oldInterval[0]) {
            // console.log('11', startYValue, _clickedYaxisSeries.yAxis.oldInterval)
            const movedValue =
              _clickedYaxisSeries.yAxis.oldInterval[0] -
              _clickedYaxisSeries.yAxis.interval[0];
            startYValue = _clickedYaxisSeries.yAxis.oldInterval[0];
            endYValue = _clickedYaxisSeries.yAxis.interval[1] - movedValue;
          }
          if (endYValue >= _clickedYaxisSeries.yAxis.oldInterval[1]) {
            // console.log('22', endYValue, _clickedYaxisSeries.yAxis.oldInterval)
            const movedValue =
              _clickedYaxisSeries.yAxis.oldInterval[1] -
              _clickedYaxisSeries.yAxis.interval[1];
            startYValue = _clickedYaxisSeries.yAxis.interval[0] + movedValue;
            endYValue = _clickedYaxisSeries.yAxis.oldInterval[1];
          }

          // console.log('起始区间', startYValue, endYValue)
          _clickedYaxisSeries.yAxis.interval = [startYValue, endYValue];
          _clearCaculatedData();

          // 调用onchange
          if (_clickedYaxisSeries.yAxis.onYIntervalChange) {
            _clickedYaxisSeries.yAxis.onYIntervalChange([
              startYValue,
              endYValue,
            ]);
          }
          _mouseMovePre = {
            x: event.offsetX,
            y: event.offsetY,
          };
        } else if (_isClickXaxisPadding) {
          // 拖动x轴
          let dragLength = 0;
          if (_mouseMovePre) {
            dragLength = endPoint.x - _mouseMovePre.x;
          } else {
            dragLength = endPoint.x - startPoint.x;
          }
          const percent =
            dragLength /
            (_container.clientWidth -
              _clickedXaxisSeries.yAxis.padding -
              _clickedXaxisSeries.yAxis.defaltPadding);
          const dragValue =
            (_clickedXaxisSeries.xAxis.interval[1] -
              _clickedXaxisSeries.xAxis.interval[0]) *
            percent;
          // //console.log(dragLength)
          // //console.log(dragValue)
          // dragLength > 0 朝右 <0 朝左
          let startXValue = _clickedXaxisSeries.xAxis.interval[0] - dragValue;
          let endXValue = _clickedXaxisSeries.xAxis.interval[1] - dragValue;

          if (startXValue <= _clickedXaxisSeries.xAxis.oldInterval[0]) {
            const movedValue =
              _clickedXaxisSeries.xAxis.interval[0] -
              _clickedXaxisSeries.xAxis.oldInterval[0];
            startXValue = _clickedXaxisSeries.xAxis.oldInterval[0];
            endXValue = _clickedXaxisSeries.xAxis.interval[1] - movedValue;
          }
          if (endXValue >= _clickedXaxisSeries.xAxis.oldInterval[1]) {
            const movedValue =
              _clickedXaxisSeries.xAxis.oldInterval[1] -
              _clickedXaxisSeries.xAxis.interval[1];
            startXValue = _clickedXaxisSeries.xAxis.interval[0] + movedValue;
            endXValue = _clickedXaxisSeries.xAxis.oldInterval[1];
          }

          _clickedXaxisSeries.xAxis.interval = [startXValue, endXValue];
          _clearCaculatedData();

          _clickedXaxisSeries.throttleOnXIntervalChange();
          //
          _mouseMovePre = {
            x: event.offsetX,
            y: event.offsetY,
          };
        } else {
          // 拖动频谱现在也相当于拖动x轴 y轴
          // buttons的值（目前只考虑只点击了一个按钮的情况）
          // buttons=1（鼠标左键）
          // buttons=2（鼠标右键）
          // buttons=3（同时按下左健和右键）
          // buttons=4（鼠标中间键）
          // buttons=5（同时按下左健和中间键）
          // buttons=6（同时按下中间健和右键）
          // buttons=7 （同时按下左健、右键和中间键)
          // 暂时左键和中键一样
          if (event.buttons == 4) {
            if (
              Math.abs(_mouseDownStart.offsetX - event.offsetX) < 20 &&
              Math.abs(_mouseDownStart.offsetY - event.offsetY) < 20
            ){
              // 拖动距离还没超过一定范围
            }else{
              // 左键拖动
              _clickedXaxisSeries.mouseStrapMeasure = {};
              let startX = startPoint.x
              let endX = endPoint.x
              let startY = _container.clientHeight - startPoint.y
              let endY = _container.clientHeight - endPoint.y
              // 不能越过边界
              if (startX < _clickedXaxisSeries.yAxis.padding) {
                startX = _clickedXaxisSeries.yAxis.padding;
              }
              if (
                startX >
                _container.clientWidth - _clickedXaxisSeries.yAxis.defaltPadding
              ) {
                startX = _container.clientWidth - _clickedXaxisSeries.yAxis.defaltPadding;
              }
              if (endY < _clickedXaxisSeries.xAxis.padding) {
                endY = _clickedXaxisSeries.xAxis.padding;
              }
              if (endY > _container.clientHeight - _clickedXaxisSeries.xAxis.defaltPadding) {
                endY = _container.clientHeight - _clickedXaxisSeries.xAxis.defaltPadding;
              }
              if (endX < _clickedXaxisSeries.yAxis.padding) {
                endX = _clickedXaxisSeries.yAxis.padding;
              }
              if (endX > _container.clientWidth - _clickedXaxisSeries.yAxis.defaltPadding) {
                endX = _container.clientWidth - _clickedXaxisSeries.yAxis.defaltPadding;
              }
              if (startY < _clickedXaxisSeries.xAxis.padding) {
                startY = _clickedXaxisSeries.xAxis.padding;
              }
              if (startY > _container.clientHeight - _clickedXaxisSeries.xAxis.defaltPadding) {
                startY = _container.clientHeight - _clickedXaxisSeries.xAxis.defaltPadding;
              }

              _clickedXaxisSeries.mouseStrapMeasure.startX = startX
              _clickedXaxisSeries.mouseStrapMeasure.endX = endX
              _clickedXaxisSeries.mouseStrapMeasure.startY = startY
              _clickedXaxisSeries.mouseStrapMeasure.endY = endY

              _clickedXaxisSeries.mouseStrapMeasure.points = []
            }
          } else if (event.buttons == 2) {
            // event.preventDefault()
            // 右键拖动
            _Series.forEach((series) => {
              let startX = startPoint.x;
              let startY = startPoint.y;
              let endX = endPoint.x;
              let endY = endPoint.y;
              // if (_Series.length > 1) {
              // 在有多个series的情况下
              // 起点不在本series内的不算
              if (
                startPoint.x < series.yAxis.padding ||
                startPoint.x >
                  _container.clientWidth - series.yAxis.defaltPadding ||
                _container.clientHeight - startPoint.y < series.xAxis.padding ||
                _container.clientHeight - startPoint.y >
                  _container.clientHeight - series.xAxis.defaltPadding
              ) {
                return;
              }
              // }

              // 不能越过边界
              if (startX < series.yAxis.padding) {
                startX = series.yAxis.padding;
              }
              if (
                startX >
                _container.clientWidth - series.yAxis.defaltPadding
              ) {
                startX = _container.clientWidth - series.yAxis.defaltPadding;
              }
              if (startY < series.xAxis.defaltPadding) {
                startY = series.xAxis.defaltPadding;
              }
              if (startY > _container.clientHeight - series.xAxis.padding) {
                startY = _container.clientHeight - series.xAxis.padding;
              }

              if (endX < series.yAxis.padding) {
                endX = series.yAxis.padding;
              }
              if (endX > _container.clientWidth - series.yAxis.defaltPadding) {
                endX = _container.clientWidth - series.yAxis.defaltPadding;
              }
              if (endY < series.xAxis.defaltPadding) {
                endY = series.xAxis.defaltPadding;
              }
              if (endY > _container.clientHeight - series.xAxis.padding) {
                endY = _container.clientHeight - series.xAxis.padding;
              }
              if (series.dragType === "zoom") {
                series.mouseStrapPoints = [];
                // y轴贯通
                series.mouseStrapPoints.push(startX);
                series.mouseStrapPoints.push(series.xAxis.padding);
                series.mouseStrapPoints.push(endX);
                series.mouseStrapPoints.push(series.xAxis.padding);
                series.mouseStrapPoints.push(endX);
                series.mouseStrapPoints.push(
                  _container.clientHeight - series.xAxis.defaltPadding
                );

                series.mouseStrapPoints.push(endX);
                series.mouseStrapPoints.push(
                  _container.clientHeight - series.xAxis.defaltPadding
                );
                series.mouseStrapPoints.push(startX);
                series.mouseStrapPoints.push(
                  _container.clientHeight - series.xAxis.defaltPadding
                );
                series.mouseStrapPoints.push(startX);
                series.mouseStrapPoints.push(series.xAxis.padding);
              } else if (series.dragType === "measure") {
                const realStartY = _getRealYValueByYPixes(
                  _container.clientHeight - startY,
                  series
                );
                const realEndY = _getRealYValueByYPixes(
                  _container.clientHeight - endY,
                  series
                );
                // 需要将realX转化成真实时间戳
                const startidx = series.yAxis.interval[1] - realStartY;
                const realstartYValue =
                  series.yAxis.timeStamps[
                    series.yAxis.timeStamps.length - 1 - Math.round(startidx)
                  ];

                const endidx = series.yAxis.interval[1] - realEndY;
                const realEndYValue =
                  series.yAxis.timeStamps[
                    series.yAxis.timeStamps.length - 1 - Math.round(endidx)
                  ];
                // 判断是否打开了timemeasure 绘制矩形
                if (series.timeMeasureOpen) {
                  series.timeMeasure = {
                    type: "time",
                    startX: startX,
                    endX: endX,
                    startY: _container.clientHeight - startY,
                    endY: _container.clientHeight - endY,
                    words: [
                      {
                        x:
                          startX -
                          _textCtx.measureText(getHHmmssSSS(realstartYValue))
                            .width,
                        y: startY + 10,
                        str: getHHmmssSSS(realstartYValue),
                      },
                      {
                        x:
                          startX -
                          _textCtx.measureText(getHHmmssSSS(realEndYValue))
                            .width,
                        y: endY,
                        str: getHHmmssSSS(realEndYValue),
                      },
                    ],
                  };
                }
              }
            });
          } else if (event.buttons == 1) {
            // 中键拖动
            let dragLength = 0;
            if (_mouseMovePre) {
              dragLength = endPoint.x - _mouseMovePre.x;
            } else {
              dragLength = endPoint.x - startPoint.x;
            }
            let percent =
              dragLength /
              (_container.clientWidth -
                _clickedXaxisSeries.yAxis.padding -
                _clickedXaxisSeries.yAxis.defaltPadding);
            let dragValue =
              (_clickedXaxisSeries.xAxis.interval[1] -
                _clickedXaxisSeries.xAxis.interval[0]) *
              percent;
            // //console.log(dragLength)
            // //console.log(dragValue)
            // dragLength > 0 朝右 <0 朝左
            let startXValue = _clickedXaxisSeries.xAxis.interval[0] - dragValue;
            let endXValue = _clickedXaxisSeries.xAxis.interval[1] - dragValue;

            if (startXValue <= _clickedXaxisSeries.xAxis.oldInterval[0]) {
              const movedValue =
                _clickedXaxisSeries.xAxis.interval[0] -
                _clickedXaxisSeries.xAxis.oldInterval[0];
              startXValue = _clickedXaxisSeries.xAxis.oldInterval[0];
              endXValue = _clickedXaxisSeries.xAxis.interval[1] - movedValue;
            }
            if (endXValue >= _clickedXaxisSeries.xAxis.oldInterval[1]) {
              const movedValue =
                _clickedXaxisSeries.xAxis.oldInterval[1] -
                _clickedXaxisSeries.xAxis.interval[1];
              startXValue = _clickedXaxisSeries.xAxis.interval[0] + movedValue;
              endXValue = _clickedXaxisSeries.xAxis.oldInterval[1];
            }

            _clickedXaxisSeries.xAxis.interval = [startXValue, endXValue];
            _clearCaculatedData();

            _clickedXaxisSeries.throttleOnXIntervalChange();

            // 向上拖动y轴
            // let realYvalue = _getRealYValueByYPixes()
            dragLength = 0;
            if (_mouseMovePre) {
              dragLength =
                _container.clientHeight -
                endPoint.y -
                (_container.clientHeight - _mouseMovePre.y);
            } else {
              dragLength =
                _container.clientHeight -
                endPoint.y -
                (_container.clientHeight - startPoint.y);
            }
            percent =
              dragLength /
              (_container.clientHeight -
                _clickedYaxisSeries.xAxis.padding -
                _clickedYaxisSeries.xAxis.defaltPadding);
            dragValue =
              (_clickedYaxisSeries.yAxis.interval[1] -
                _clickedYaxisSeries.yAxis.interval[0]) *
              percent;
            // dragLength > 0 朝上 <0 朝下
            let startYValue = _clickedYaxisSeries.yAxis.interval[0] - dragValue;
            let endYValue = _clickedYaxisSeries.yAxis.interval[1] - dragValue;
            if (startYValue <= _clickedYaxisSeries.yAxis.oldInterval[0]) {
              // console.log('11', startYValue, _clickedYaxisSeries.yAxis.oldInterval)
              const movedValue =
                _clickedYaxisSeries.yAxis.oldInterval[0] -
                _clickedYaxisSeries.yAxis.interval[0];
              startYValue = _clickedYaxisSeries.yAxis.oldInterval[0];
              endYValue = _clickedYaxisSeries.yAxis.interval[1] - movedValue;
            }
            if (endYValue >= _clickedYaxisSeries.yAxis.oldInterval[1]) {
              // console.log('22', endYValue, _clickedYaxisSeries.yAxis.oldInterval)
              const movedValue =
                _clickedYaxisSeries.yAxis.oldInterval[1] -
                _clickedYaxisSeries.yAxis.interval[1];
              startYValue = _clickedYaxisSeries.yAxis.interval[0] + movedValue;
              endYValue = _clickedYaxisSeries.yAxis.oldInterval[1];
            }

            // console.log('起始区间', startYValue, endYValue)
            _clickedYaxisSeries.yAxis.interval = [startYValue, endYValue];
            _clearCaculatedData();

            // 调用onchange
            if (_clickedYaxisSeries.yAxis.onYIntervalChange) {
              _clickedYaxisSeries.yAxis.onYIntervalChange([
                startYValue,
                endYValue,
              ]);
            }
          }

          _mouseMovePre = {
            x: event.offsetX,
            y: event.offsetY,
          };
        }
        _refresh();
      } else {
        const x = event.offsetX;
        const y = event.offsetY;
        _isClickMarkLine = false;
        _clickedMarkLine = null;
        _clickedMarkLineSeries = null;

        // 判断鼠标是否移动到了测量区域的四条边上
        const measureZoneFindResult = _findNearestMeasureZone(x, y);
        if (measureZoneFindResult) {
          if (measureZoneFindResult.direction === "left") {
            _textcontainer.style.cursor = "ew-resize";
          } else if (measureZoneFindResult.direction === "left-top") {
            _textcontainer.style.cursor = "nw-resize";
          } else if (measureZoneFindResult.direction === "left-bottom") {
            _textcontainer.style.cursor = "ne-resize";
          } else if (measureZoneFindResult.direction === "right") {
            _textcontainer.style.cursor = "ew-resize";
          } else if (measureZoneFindResult.direction === "right-top") {
            _textcontainer.style.cursor = "sw-resize";
          } else if (measureZoneFindResult.direction === "right-bottom") {
            _textcontainer.style.cursor = "se-resize";
          } else if (measureZoneFindResult.direction === "bottom") {
            _textcontainer.style.cursor = "ns-resize";
          } else if (measureZoneFindResult.direction === "top") {
            _textcontainer.style.cursor = "ns-resize";
          } else if (measureZoneFindResult.direction === "all") {
            _textcontainer.style.cursor = "move";
          } else {
            _textcontainer.style.cursor = "";
          }
          _isClickMeasureZone = true;
          _clickedMeasureZone = measureZoneFindResult;
          _clickedMeasureZoneSeries = measureZoneFindResult.series;
        } else {
          _isClickMeasureZone = false;
          _clickedMeasureZone = null;
          _clickedMeasureZoneSeries = null;
        }

        // 判断鼠标是否移动到了测量区域中（拖动）
        const measureZoneDragResult = _findDragInMeasureZone(x, y);

        if (measureZoneDragResult) {
          if (measureZoneDragResult.direction === "all") {
            _textcontainer.style.cursor = "move";
          } else {
            _textcontainer.style.cursor = "";
          }
          _isClickToDragMeasureZone = true;
          _clickedToDragMeasureZone = measureZoneDragResult;
          // _clickedMeasureZoneSeries = measureZoneFindResult.series
          return;
        } else {
          _isClickToDragMeasureZone = false;
          _clickedToDragMeasureZone = null;
          // _clickedMeasureZoneSeries = null
        }

        if (!_isClickMeasureZone && !_isClickToDragMeasureZone) {
          // 判断鼠标是否移动到了markLine上面
          const markFindResult = _findNearestMarkLine(x, y);

          if (markFindResult) {
            if (markFindResult.markLine.type === "x") {
              _textcontainer.style.cursor = "ew-resize";
            }
            if (markFindResult.markLine.type === "y") {
              _textcontainer.style.cursor = "ns-resize";
            }
            _isClickMarkLine = true;
            _clickedMarkLine = markFindResult.markLine;
            _clickedMarkLineSeries = markFindResult.series;
          } else {
            _textcontainer.style.cursor = "";
            _isClickMarkLine = false;
          }
        }

        // 判断鼠标是否移入了鼠标拖动测量区域中
        if(!_isClickMeasureZone &&
          !_isClickToDragMeasureZone &&
          !_isClickMarkLine){
            // 判断鼠标是否移动到了markLine上面
            const mousestrapMeasureFindResult = _findDragInMouseStrapMeasure(x, y);
            if(mousestrapMeasureFindResult){
              _isClickMouseStrapMeasure = true;
            }else{
              _isClickMouseStrapMeasure = false;
            }
        }
        if (
          !_isClickMeasureZone &&
          !_isClickToDragMeasureZone &&
          !_isClickMarkLine
        ) {
          // 判断当前是否移动到了yaxis左边的区域(需要)
          _isClickYaxisPadding = false;

          _Series.forEach((series) => {
            // if (_config.type === 'pubu') {
            //     // 瀑布流不判断y轴放大
            //     return
            // }
            if (
              x < series.yAxis.padding &&
              _container.clientHeight - y > series.xAxis.padding &&
              _container.clientHeight - y <
                _container.clientHeight - series.xAxis.defaltPadding
            ) {
              _clickedYaxisSeries = series;
              _isClickYaxisPadding = true;
            }
          });
          if (_isClickYaxisPadding) {
            _textcontainer.style.cursor = "pointer";
            return;
          } else {
            _textcontainer.style.cursor = "";
          }
          if (!_isClickYaxisPadding) {
            // 判断当前是否移动到了xaxis下边的区域(需要)
            _isClickXaxisPadding = false;
            _Series.forEach((series) => {
              if (_config.type === "pubu") {
                // 瀑布流x轴可以拖动
                // return
              }
              // 现在整个图表区域都能拖动
              _clickedXaxisSeries = series;
              _clickedYaxisSeries = series;
              if (_container.clientHeight - y < series.xAxis.padding) {
                _isClickXaxisPadding = true;
              }
            });
            if (_isClickXaxisPadding) {
              _textcontainer.style.cursor = "pointer";
              return;
            } else {
              _textcontainer.style.cursor = "";
            }
          }
        }

        // 计算当前鼠标位置的xy值
        _Series.forEach((series) => {
          // 不能越过边界
          if (x < _Series[0].yAxis.padding) {
            return;
          }
          if (x > _container.clientWidth - _Series[0].yAxis.defaltPadding) {
            return;
          }
          if (y < _Series[0].xAxis.defaltPadding) {
            return;
          }
          if (y > _container.clientHeight - _Series[0].xAxis.padding) {
            return;
          }
          if (_config.type === "line") {
            const realX = _getRealXValueByXPixes(x, series);
            // y坐标从下往上递增
            const realY = _getRealYValueByYPixes(
              _container.clientHeight - y,
              series
            );
            // 查看鼠标是否移动到y轴mark上了
            if (series.onMouseMoveListener) {
              series.onMouseMoveListener(realX, realY, event);
            }
          } else if (_config.type === "pubu") {
            if (series.yAxis.timeStamps.length === 0) {
              return;
            }
            const realX = _getRealXValueByXPixes(x, series);
            // y坐标从下往上递增
            const realY = _getRealYValueByYPixes(
              _container.clientHeight - y,
              series
            );
            // 查看鼠标是否移动到y轴mark上了
            // 需要将realX转化成真实时间戳
            const idx = series.yAxis.interval[1] - realY;
            const realYValue =
              series.yAxis.timeStamps[
                series.yAxis.timeStamps.length - 1 - Math.round(idx)
              ];

            if (series.onMouseMoveListener) {
              series.onMouseMoveListener(realX, realYValue, event);
            }
          }
        });
      }
    };
  }

  function _doOnXIntervalChange(series, interval) {
    // 当坐标系变化的时候 重新计算一些数据
    if (series.kdCollectionOpen) {
      if (series.kdCollection) {
        const kdCollectionPositionValue =
          series.kdCollection.kdCollectionPositionValue;
        const kdCollectionPosition = _getXPixesByXvalue(
          kdCollectionPositionValue,
          series
        );

        // //console.log("kdCollectionPositionValue:" +kdCollectionPositionValue)
        // //console.log("kdCollectionPosition:" +kdCollectionPosition)

        // //console.log((series.kdCollectionWidth/(series.xAxis.interval[1] - series.xAxis.interval[0])))
        const collectonZoneWidth =
          (series.kdCollectionWidth /
            (series.xAxis.interval[1] - series.xAxis.interval[0])) *
          (_container.clientWidth -
            series.yAxis.padding -
            series.yAxis.defaltPadding);

        // //console.log("collectonZoneWidth:" +collectonZoneWidth)
        series.kdCollection = {
          type: "kdCollection",
          kdCollectionPosition: kdCollectionPosition,
          kdCollectionPositionValue: kdCollectionPositionValue,
          collectonZoneWidth: collectonZoneWidth,
          startX: kdCollectionPosition - collectonZoneWidth / 2,
          endX: kdCollectionPosition + collectonZoneWidth / 2,
          startY: series.xAxis.padding,
          endY: _container.clientHeight - series.xAxis.defaltPadding,
          points: [],
          words: [],
        };
      }
    }
    // _refresh()
    if (series.xAxis.onXIntervalChange) {
      series.xAxis.onXIntervalChange(interval);
    }
  }

  function _doOnclick(event) {
    if (_onclickTimer) {
      clearTimeout(_onclickTimer);
      _onclickTimer = null;
      // 已经是第二次点击了 直接执行
      _realDoOnclick(event);
    } else {
      // 已经是第一次点击了 设置定时任务
      _onclickTimer = setTimeout(() => {
        _realDoOnclick(event);
        _onclickTimer = null;
      }, 100);
    }
  }

  function _realDoOnclick(event) {
    const x = event.offsetX;
    const y = event.offsetY;
    _Series.forEach((series) => {
      // 不能越过边界
      if (x < _Series[0].yAxis.padding) {
        return;
      }
      if (x > _container.clientWidth - _Series[0].yAxis.defaltPadding) {
        return;
      }
      if (y < _Series[0].xAxis.defaltPadding) {
        return;
      }
      if (y > _container.clientHeight - _Series[0].xAxis.padding) {
        return;
      }
      if (_config.type === "line") {
        const realX = _getRealXValueByXPixes(x, series);
        // y坐标从下往上递增
        const realY = _getRealYValueByYPixes(
          _container.clientHeight - y,
          series
        );
        // 查看鼠标是否移动到y轴mark上了
        if (series.onclickListener) {
          series.onclickListener(realX, realY, event);
        }
      } else if (_config.type === "pubu") {
        if (series.yAxis.timeStamps.length === 0) {
          return;
        }
        const realX = _getRealXValueByXPixes(x, series);
        // y坐标从下往上递增
        const realY = _getRealYValueByYPixes(
          _container.clientHeight - y,
          series
        );
        // 查看鼠标是否移动到y轴mark上了
        // 需要将realX转化成真实时间戳
        const idx = series.yAxis.interval[1] - realY;
        const realYValue =
          series.yAxis.timeStamps[
            series.yAxis.timeStamps.length - 1 - Math.round(idx)
          ];

        if (series.onclickListener) {
          series.onclickListener(realX, realYValue, event);
        }
      }
    });
  }

  function _findDragInMouseStrapMeasure(x, y) {
    let finded = false;
    let result = null;
    const yPixes = _container.clientHeight - y;
    _Series.forEach((series) => {
      // 判断是否在series范围内
      if (
        x < series.yAxis.padding ||
        x > _container.clientWidth - series.yAxis.defaltPadding ||
        yPixes < series.xAxis.padding ||
        yPixes > _container.clientHeight - series.xAxis.defaltPadding
      ) {
        return;
      }
      // 如果已经判断点击了其他series的mouseStrapMeasure 就不计算当前的series里面的了
      if (finded) {
        return;
      }
      // 先判断SNRMeasure
      if (series.mouseStrapMeasure) {
        if (
          x < series.mouseStrapMeasure.endX &&
          x > series.mouseStrapMeasure.startX &&
          // 这里startY和endY是相反的 因为拖动时是从上到下
          yPixes < series.mouseStrapMeasure.startY &&
          yPixes > series.mouseStrapMeasure.endY
        ) {
          finded = true;
          result = {
            measureZone: series.mouseStrapMeasure,
            series: series,
            direction: "all",
          };
        }
      }
      if (finded) {
        return;
      }
    });
    return result;
  }

  function _findNearestMarkLine(x, y) {
    let result = null;
    // 判断是否拉动markline
    let _nearestXMarkLineIndex = -1;
    let finded = false;
    _Series.forEach((series) => {
      // 判断是否在series范围内
      if (
        x < series.yAxis.padding ||
        x > _container.clientWidth - series.yAxis.defaltPadding ||
        y < series.xAxis.padding ||
        y > _container.clientHeight - series.xAxis.defaltPadding
      ) {
        return;
      }
      // 如果已经判断点击了其他series的markline 就不计算当前的series里面的了
      if (finded) {
        return;
      }
      series.xAxis.markLines.forEach((markLine, index) => {
        if (markLine.visible == false) {
          return;
        }
        const distance = Math.abs(x - markLine.pixes);
        if (distance < 5) {
          finded = true;
          if (_nearestXMarkLineIndex === -1) {
            _nearestXMarkLineIndex = index;
            result = {
              markLine: markLine,
              series: series,
            };
          } else {
            if (
              Math.abs(
                x - series.xAxis.markLines[_nearestXMarkLineIndex].pixes
              ) > Math.abs(x - markLine.pixes)
            ) {
              _nearestXMarkLineIndex = index;
              result = {
                markLine: markLine,
                series: series,
              };
            }
          }
        }
      });
      if (finded) {
        return;
      }
      let _nearestYMarkLineIndex = -1;
      series.yAxis.markLines.forEach((markLine, index) => {
        const distance = Math.abs(_container.clientHeight - y - markLine.pixes);
        if (distance < 5) {
          if (_nearestYMarkLineIndex === -1) {
            _nearestYMarkLineIndex = index;
            result = {
              markLine: markLine,
              series: series,
            };
          } else {
            if (
              Math.abs(
                _container.clientHeight -
                  y -
                  series.yAxis.markLines[_nearestYMarkLineIndex].pixes
              ) > Math.abs(_container.clientHeight - y - markLine.pixes)
            ) {
              _nearestYMarkLineIndex = index;
              result = {
                markLine: markLine,
                series: series,
              };
            }
          }
        }
      });
    });
    return result;
  }

  function _findDragInMeasureZone(x, y) {
    let finded = false;
    let result = null;
    const yPixes = _container.clientHeight - y;
    _Series.forEach((series) => {
      // 判断是否在series范围内
      if (
        x < series.yAxis.padding ||
        x > _container.clientWidth - series.yAxis.defaltPadding ||
        yPixes < series.xAxis.padding ||
        yPixes > _container.clientHeight - series.xAxis.defaltPadding
      ) {
        return;
      }
      // 如果已经判断点击了其他series的measurezone 就不计算当前的series里面的了
      if (finded) {
        return;
      }
      // 先判断SNRMeasure
      if (series.SNRMeasureOpen && series.SNRMeasure) {
        if (
          x < series.SNRMeasure.endX &&
          x > series.SNRMeasure.startX &&
          yPixes < series.SNRMeasure.endY &&
          yPixes > series.SNRMeasure.startY
        ) {
          finded = true;
          result = {
            measureZone: series.SNRMeasure,
            series: series,
            direction: "all",
          };
        }
      }
      if (finded) {
        return;
      }
      // 再寻找 freqMeasure
      if (series.freqMeasureOpen && series.freqMeasure) {
        if (
          x < series.freqMeasure.endX &&
          x > series.freqMeasure.startX &&
          yPixes < series.freqMeasure.endY &&
          yPixes > series.freqMeasure.startY
        ) {
          finded = true;
          result = {
            measureZone: series.freqMeasure,
            series: series,
            direction: "all",
          };
        }
      }
      if (finded) {
        return;
      }
      // 再寻找 freqMeasure
      if (series.timeMeasureOpen && series.timeMeasure) {
        if (
          x < series.timeMeasure.endX &&
          x > series.timeMeasure.startX &&
          yPixes < series.timeMeasure.endY &&
          yPixes > series.timeMeasure.startY
        ) {
          finded = true;
          result = {
            measureZone: series.timeMeasure,
            series: series,
            direction: "all",
          };
        }
      }
    });
    return result;
  }

  /**
   * 寻找鼠标在哪个测量区域的边上
   * @param {*} x
   * @param {*} y
   * @returns
   */
  function _findNearestMeasureZone(x, y) {
    // 判断是否拉动markline
    let finded = false;
    let result = null;
    _Series.forEach((series) => {
      // 判断是否在series范围内
      if (
        x < series.yAxis.padding ||
        x > _container.clientWidth - series.yAxis.defaltPadding ||
        y < series.xAxis.padding ||
        y > _container.clientHeight - series.xAxis.defaltPadding
      ) {
        return;
      }
      // 如果已经判断点击了其他series的measurezone 就不计算当前的series里面的了
      if (finded) {
        return;
      }
      // 先判断SNRMeasure
      if (series.SNRMeasureOpen && series.SNRMeasure) {
        const xPixes = x;
        const yPixes = _container.clientHeight - y;
        // 判断是否在测量x轴的measurezone上
        let distance = 99999;
        // 先判断是不是在左上，右上 左下右下的地方

        if(Math.abs(yPixes - series.SNRMeasure.endY) < 5  && Math.abs(x - series.SNRMeasure.startX) < 5){
          // 在左上角
          finded = true;
          result = {
            measureZone: series.SNRMeasure,
            series: series,
            direction: "left-top",
          };
          return;
        }

        if(Math.abs(yPixes - series.SNRMeasure.endY) < 5  && Math.abs(x - series.SNRMeasure.endX) < 5){
          // 在右上角
          finded = true;
          result = {
            measureZone: series.SNRMeasure,
            series: series,
            direction: "right-top",
          };
          return;
        }

        if(Math.abs(yPixes - series.SNRMeasure.startY) < 5  && Math.abs(x - series.SNRMeasure.startX) < 5){
          // 在左下角
          finded = true;
          result = {
            measureZone: series.SNRMeasure,
            series: series,
            direction: "left-bottom",
          };
          return;
        }

        if(Math.abs(yPixes - series.SNRMeasure.startY) < 5  && Math.abs(x - series.SNRMeasure.endX) < 5){
          // 在右下角
          finded = true;
          result = {
            measureZone: series.SNRMeasure,
            series: series,
            direction: "right-bottom",
          };
          return;
        }


        distance = Math.abs(yPixes - series.SNRMeasure.startY);
        if (
          distance < 5 &&
          x > series.SNRMeasure.startX &&
          x < series.SNRMeasure.endX
        ) {
          finded = true;
          result = {
            measureZone: series.SNRMeasure,
            series: series,
            direction: "bottom",
          };
        }
        distance = Math.abs(yPixes - series.SNRMeasure.endY);
        if (
          distance < 5 &&
          x > series.SNRMeasure.startX &&
          x < series.SNRMeasure.endX
        ) {
          finded = true;
          result = {
            measureZone: series.SNRMeasure,
            series: series,
            direction: "top",
          };
        }
        distance = Math.abs(x - series.SNRMeasure.startX)
        if(distance < 5 && (yPixes>series.SNRMeasure.startY && yPixes<series.SNRMeasure.endY)){
          finded = true
          result = {
            measureZone: series.SNRMeasure,
            series: series,
            direction: 'left'
          }
        }
        distance = Math.abs(x - series.SNRMeasure.endX)
        if(distance < 5 && (yPixes>series.SNRMeasure.startY && yPixes<series.SNRMeasure.endY)){
          finded = true
          result = {
            measureZone: series.SNRMeasure,
            series: series,
            direction: 'right'
          }
        }
      }
      if (result) {
        return;
      }
      // 再寻找 freqMeasure
      if (series.freqMeasureOpen && series.freqMeasure) {
        const xPixes = x;
        const yPixes = _container.clientHeight - y;
        // 判断是否在测量x轴的measurezone上
        let distance = 99999;
        distance = Math.abs(x - series.freqMeasure.startX);
        if (
          distance < 5 &&
          yPixes > series.freqMeasure.startY &&
          yPixes < series.freqMeasure.endY
        ) {
          finded = true;
          result = {
            measureZone: series.freqMeasure,
            series: series,
            direction: "left",
          };
        }
        distance = Math.abs(x - series.freqMeasure.endX);
        if (
          distance < 5 &&
          yPixes > series.freqMeasure.startY &&
          yPixes < series.freqMeasure.endY
        ) {
          finded = true;
          result = {
            measureZone: series.freqMeasure,
            series: series,
            direction: "right",
          };
        }
      }

      // 再寻找 kdCollection
      if (series.kdCollectionOpen && series.kdCollection) {
        const xPixes = x;
        const yPixes = _container.clientHeight - y;
        // 判断鼠标是否在采集区域内
        let distance = 99999;
        distance = Math.abs(x - series.kdCollection.startX);
        if (
          series.kdCollection.startX < x &&
          x < series.kdCollection.endX &&
          series.kdCollection.startY < yPixes &&
          yPixes < series.kdCollection.endY
        ) {
          finded = true;
          result = {
            measureZone: series.kdCollection,
            series: series,
            direction: "all",
          };
        }
      }

      // 再寻找 timeMeasure
      if (series.timeMeasureOpen && series.timeMeasure) {
        const xPixes = x;
        const yPixes = _container.clientHeight - y;
        // 判断是否在测量y轴的timeMeasure上
        let distance = 99999;
        distance = Math.abs(yPixes - series.timeMeasure.startY);
        if (
          distance < 5 &&
          x > series.timeMeasure.startX &&
          x < series.timeMeasure.endX
        ) {
          finded = true;
          result = {
            measureZone: series.timeMeasure,
            series: series,
            direction: "bottom",
          };
        }
        distance = Math.abs(yPixes - series.timeMeasure.endY);
        if (
          distance < 5 &&
          x > series.timeMeasure.startX &&
          x < series.timeMeasure.endX
        ) {
          finded = true;
          result = {
            measureZone: series.timeMeasure,
            series: series,
            direction: "top",
          };
        }
      }
    });
    return result;
  }

  function getHHmmssSSS(time) {
    if (!time) {
      return "--:--:--.---";
    }
    const date = new Date(time);
    const hour =
      date.getHours().toString().length > 1
        ? date.getHours()
        : "0" + date.getHours();
    const minutes =
      date.getMinutes().toString().length > 1
        ? date.getMinutes()
        : "0" + date.getMinutes();
    const seconds =
      date.getSeconds().toString().length > 1
        ? date.getSeconds()
        : "0" + date.getSeconds();
    const result =
      hour + ":" + minutes + ":" + seconds + "." + date.getMilliseconds();
    return result;
  }

  function getmmssSSS(time) {
    if (!time) {
      // return '--:--:--.---'
      return "";
    }
    const date = new Date(time);
    const minutes =
      date.getMinutes().toString().length > 1
        ? date.getMinutes()
        : "0" + date.getMinutes();
    /* const seconds =
            date.getSeconds().toString().length > 1
                ? date.getSeconds()
                : '0' + date.getSeconds() */
    const seconds = date.getSeconds();
    const result =
      // '00' + ':' + minutes + ':' + seconds + '.' + date.getMilliseconds()
      seconds + "." + date.getMilliseconds() + "s";
    return result;
  }

  /**
   * 根据x轴的坐标值得到x轴的实际值(使用_axisMatrix的参考系,即边界为container内,方便进行坐标的计算)
   */
  function _getRealXValueByXPixes(x, series) {
    const percent =
      (x - series.yAxis.padding) /
      (_container.clientWidth -
        series.yAxis.padding -
        series.yAxis.defaltPadding);
    const result =
      (series.xAxis.interval[1] - series.xAxis.interval[0]) * percent +
      series.xAxis.interval[0];
    return result;
  }
  /**
   * 根据y轴的坐标值得到y轴的实际值(使用_axisMatrix的参考系,即边界为container内,方便进行坐标的计算)
   */
  function _getRealYValueByYPixes(y, series) {
    const percent =
      (y - series.xAxis.padding) /
      (_container.clientHeight -
        series.xAxis.padding -
        series.xAxis.defaltPadding);
    const result =
      (series.yAxis.interval[1] - series.yAxis.interval[0]) * percent +
      series.yAxis.interval[0];
    return result;
  }
  /**
   * 根据y的实际值得到y的坐标值(使用_axisMatrix的参考系,即边界为container内,方便进行坐标的计算)
   * @param {*} y
   */
  function _getYPixesByYvalue(y, series) {
    const yPercent =
      (y - series.yAxis.interval[0]) /
      (series.yAxis.interval[1] - series.yAxis.interval[0]);
    // var transformedY = (_container.clientHeight - 50 - 10) * newYPercent
    const result =
      series.xAxis.padding +
      (_container.clientHeight -
        series.xAxis.padding -
        series.xAxis.defaltPadding) *
        yPercent;
    return result;
  }
  /**
   * 根据x的实际值得到x的坐标值(使用_axisMatrix的参考系,即边界为container内,方便进行坐标的计算)
   * @param {*} y
   */
  function _getXPixesByXvalue(x, series) {
    const xPercent =
      (x - series.xAxis.interval[0]) /
      (series.xAxis.interval[1] - series.xAxis.interval[0]);
    // var transformedY = (_container.clientHeight - 50 - 10) * newYPercent
    const result =
      series.yAxis.padding +
      (_container.clientWidth -
        series.yAxis.padding -
        series.yAxis.defaltPadding) *
        xPercent;
    return result;
  }

  /**
   * 根据y的实际值得到y的坐标值(使用_lineMatrix的参考系,即边界为axis内部,方便进行坐标的计算)
   * @param {*} y
   */
  function _getYPixesByYvalueOnLineMatrix(y, series) {
    const yPercent =
      (y - series.yAxis.interval[0]) /
      (series.yAxis.interval[1] - series.yAxis.interval[0]);
    // var transformedY = (_container.clientHeight - 50 - 10) * newYPercent
    const result =
      (_container.clientHeight -
        series.xAxis.padding -
        series.xAxis.defaltPadding) *
      yPercent;
    return result;
  }
  /**
   * 根据x的实际值得到x的坐标值(使用_lineMatrix的参考系,即边界为axis内部,方便进行坐标的计算)
   * @param {*} y
   */
  function _getXPixesByXvalueOnLineMatrix(x, series) {
    const xPercent =
      (x - series.xAxis.interval[0]) /
      (series.xAxis.interval[1] - series.xAxis.interval[0]);
    // var transformedY = (_container.clientHeight - 50 - 10) * newYPercent
    const result =
      (_container.clientWidth -
        series.yAxis.padding -
        series.yAxis.defaltPadding) *
      xPercent;
    return result;
  }

  /**
   * 二分查找某个值所对应色带上的颜色
   * @param {*} colors
   * @param {*} val
   * @returns
   */
  function _searchColor(colors, val) {
    // let startPosition = 0
    // let endPosition = 0
    // for (let j = 0; j < colors.length; j++) {
    //   if (colors[j].value > val) {
    //     endPosition = j
    //     if (j - 1 > 0) {
    //       startPosition = j - 1
    //     } else {
    //       startPosition = 0
    //     }
    //     break
    //   }
    //   if (j === colors.length - 1) {
    //     startPosition = j
    //     endPosition = j
    //   }
    // }
    // return startPosition

    let left = 0;
    let right = colors.length - 1;
    let mid = 0;

    while (left <= right) {
      mid = parseInt(left + (right - left) / 2); // 计算中间元素的索引
      if (colors[mid].value < val) {
        left = mid + 1; // 目标值在右半部分
      } else {
        right = mid - 1; // 目标值在左半部分
      }
    }
    return mid;
  }

  function _getRGB(colors, val) {
    const temObj = {
      r: 255,
      g: 0,
      b: 0,
    };
    console.log(colors);
    /* colors.some((item, index) => {
          if (index !== colors.length - 1 && val > item.value) {
            const persent = ((val - item.value) / (colors[index + 1].value - item.value))
            temObj.r = (colors[index + 1].color.r - item.color.r) * persent
            temObj.g = (colors[index + 1].color.g - item.color.g) * persent
            temObj.b = (colors[index + 1].color.b - item.color.b) * persent
            return true
          } else if (index === colors.length - 1 && val > item.value) {
            const persent = ((val - item.value) / (item.value - colors[index - 1].value))
          }
        }) */

    return temObj;
  }

  return {
    /**
     * 罗盘图
     */
    compass(config) {
      _config = {
        type: "compass",
        container: config.container,
        background: config.background
          ? config.background
          : {
              r: 0,
              g: 0,
              b: 0,
            },
      };
      _compassConfig.wordColor = config.wordColor
        ? config.wordColor
        : {
            r: 1,
            g: 1,
            b: 1,
          };
      _initGl();
      _addCompassMouseEventListener();
      return {
        refresh() {
          _refresh();
        },
        setMeasureListener(listener) {
          _compassConfig.compassMeasureListener = listener;
        },
        setPointAngle(angle) {
          _compassConfig.compassPointRotation = (angle / 360) * 2 * Math.PI;
          _compassConfig.compassPointOldRotation =
            _compassConfig.compassPointRotation;
          _refresh();
        },
        setPoints(data) {
          if (data && data.length > 0) {
            const tmpPoints = [];
            const tmpPointSizes = [];
            const banjing = _container.clientHeight / 2 - 5;
            data.forEach((item) => {
              const theta = (item.angle * Math.PI) / 180;
              const x1 = 0 + item.amplitude * banjing * Math.sin(theta);
              const y1 = 0 + item.amplitude * banjing * Math.cos(theta);
              // tmpPoints = tmpPoints.concat([x1, y1])
              // tmpPoints.push({
              //   x: x1,
              //   y: y1
              // })
              tmpPoints.push({
                x: x1,
                y: y1,
                xToRect: 0,
                yToRect: banjing * item.amplitude,
                angle: item.angle,
                color: item.color ? item.color : { r: 0, g: 1, b: 1 },
              });
              tmpPointSizes.push(5);
            });
            _compassConfig.comapssPoints = tmpPoints;
            _compassConfig.comapssPointsSizes = tmpPointSizes;
            // 重新计算点坐标
            _compassConfig.comapssShowPoints = [];
            _refresh();
          }
        },
        setConfidence(confidence) {
          _compassConfig.confidence = confidence;
          _refresh();
        },
        setPointSize(pointSize) {
          _compassConfig.pointSize = pointSize;
          _refresh();
        },
        setCarPositionRotation(angle) {
          _compassConfig.compassCarPositionRotation =
            (angle / 360) * 2 * Math.PI;
          _compassConfig.compassCarPositionMatrix = null;
        },
        setCompassScaleRotation(angle) {
          _compassConfig.compassScaleRotation = (angle / 360) * 2 * Math.PI;
          _compassConfig.compassMatrix = null;
          _compassConfig.compassPointMatrix = null;
        },
        // 清空数据
        clear() {
          _compassConfig.confidence = null;
          _compassConfig.comapssPoints = [];
          _compassConfig.comapssPointsSizes = [];
          _compassConfig.comapssShowPoints = [];
          _compassConfig.compassPointRotation = null;
          _compassConfig.compassPointOldRotation = null;
          _compassConfig.pointShowJiaoDuChange = null;
          _refresh();
        },
        reSize() {
          const div = document.querySelector("#" + _config.container);
          _container.width = div.clientWidth;
          _container.height = div.clientHeight;
          _textCtx.width = div.clientWidth;
          _textCtx.height = div.clientHeight;
          _clearCaculatedData();
          _refresh();
        },
      };
    },
    /**
     * 瀑布图
     */
    pubu(config) {
      _config = {
        type: "pubu",
        container: config.container,
        background:
          config.background != null
            ? config.background
            : {
                r: 0,
                g: 0,
                b: 0,
              },
      };
      _initGl();
      _addMouseEventListener();
      return {
        addSeries(seriesConfig) {
          if (!seriesConfig) {
            seriesConfig = {
              xAxisInterval: [0, 100],
              xAxisPadding: 30,
              xAxisAnotherPadding: 10,
              xAxisMarkNum: 5,
              yAxisInterval: [0, seriesConfig.row],
              yAxisPadding: 30,
              yAxisAnotherPadding: 30,
              yAxisMarkNum: 5,
              zoomYAxisInMouseWheelOnSerires: false,
              column: 1024,
              row: 60,
              direction: "topToBottom",
              axisColor: {
                r: 1,
                g: 1,
                b: 1,
                a: 1,
              },
              showColors: false,
              timeStampFormatter: "hh:mm:ss",
              // 瀑布图是否展示全部数据（是的话不处理x轴偏移量）
              showAllData: false,
              measureTextColor: {
                r: 1,
                g: 1,
                b: 1,
                a: 1,
              },
            };
          } else {
            seriesConfig = {
              title: seriesConfig.title
                ? seriesConfig.title
                : { text: "", top: 0, left: 0 },
              axisXUnits: seriesConfig.axisXUnits
                ? seriesConfig.axisXUnits
                : { text: "", top: 0, left: 0 },
              axisYUnits: seriesConfig.axisYUnits
                ? seriesConfig.axisYUnits
                : { text: "", top: 0, left: 0 },
              tooltip: seriesConfig.tooltip
                ? seriesConfig.tooltip
                : { value1: "", value2: "", top: 0, left: 0 },
              xAxisInterval: seriesConfig.xAxisInterval
                ? seriesConfig.xAxisInterval
                : [0, 100],
              xAxisPadding: seriesConfig.xAxisPadding
                ? seriesConfig.xAxisPadding
                : 30,
              xAxisAnotherPadding:
                seriesConfig.xAxisAnotherPadding != null
                  ? seriesConfig.xAxisAnotherPadding
                  : 30,
              xAxisMarkNum: seriesConfig.xAxisMarkNum
                ? seriesConfig.xAxisMarkNum
                : 5,
              zoomYAxisInMouseWheelOnSerires:
                seriesConfig.zoomYAxisInMouseWheelOnSerires != null
                  ? seriesConfig.zoomYAxisInMouseWheelOnSerires
                  : false,
              xAxisMarkFormatter: seriesConfig.xAxisMarkFormatter,
              yAxisInterval: [-seriesConfig.row, 0],
              yAxisPadding: seriesConfig.yAxisPadding
                ? seriesConfig.yAxisPadding
                : 30,
              yAxisAnotherPadding: seriesConfig.yAxisAnotherPadding
                ? seriesConfig.yAxisAnotherPadding
                : 30,
              yAxisMarkNum: seriesConfig.yAxisMarkNum
                ? seriesConfig.yAxisMarkNum
                : 5,
              yAxisMarkFormatter: seriesConfig.yAxisMarkFormatter,
              minXInterval: seriesConfig.minXInterval,
              column: seriesConfig.column,
              row: seriesConfig.row,
              direction: seriesConfig.direction
                ? seriesConfig.direction
                : "topToBottom",
              axisColor: seriesConfig.axisColor
                ? seriesConfig.axisColor
                : {
                    r: 1,
                    g: 1,
                    b: 1,
                    a: 1,
                  },
              showColors: seriesConfig.showColors
                ? seriesConfig.showColors
                : false,
              timeStampFormatter: seriesConfig.timeStampFormatter
                ? seriesConfig.timeStampFormatter
                : "hh:mm:ss",
              showAllData: seriesConfig.showAllData
                ? seriesConfig.showAllData
                : false,
              measureTextColor: seriesConfig.measureTextColor
                ? seriesConfig.measureTextColor
                : {
                    r: 1,
                    g: 1,
                    b: 1,
                    a: 1,
                  },
            };
          }
          const newSeries = {
            title: seriesConfig.title,
            axisXUnits: seriesConfig.axisXUnits,
            axisYUnits: seriesConfig.axisYUnits,
            tooltip: seriesConfig.tooltip,
            direction: seriesConfig.direction,
            column: seriesConfig.column ? seriesConfig.column : 1024,
            row: seriesConfig.row ? seriesConfig.row : 60,
            xAxis: {
              interval: seriesConfig.xAxisInterval,
              oldInterval: [
                seriesConfig.xAxisInterval[0],
                seriesConfig.xAxisInterval[1],
              ],
              padding: seriesConfig.xAxisPadding,
              defaltPadding: seriesConfig.xAxisAnotherPadding,
              markNum: seriesConfig.xAxisMarkNum, // 刻度数量
              xAxisMarkFormatter: seriesConfig.xAxisMarkFormatter,
              minXInterval: seriesConfig.minXInterval,
              color: {
                r: seriesConfig.axisColor.r,
                g: seriesConfig.axisColor.g,
                b: seriesConfig.axisColor.b,
                a: seriesConfig.axisColor.a,
              },
              points: [],
              words: [],
              markLines: [],
              markZones: [],
              markZonesHighLight: [],
              markZonesOfBlackList: [],
              markZonePoints: [],
              markZonePointColors: [],
            },
            yAxis: {
              interval: seriesConfig.yAxisInterval,
              oldInterval: [
                seriesConfig.yAxisInterval[0],
                seriesConfig.yAxisInterval[1],
              ],
              padding: seriesConfig.yAxisPadding,
              defaltPadding: seriesConfig.yAxisAnotherPadding,
              markNum: seriesConfig.yAxisMarkNum,
              yAxisMarkFormatter: (value) => {
                // seriesConfig.yAxisMarkFormatter,
                // if (Math.round(value) < 0) {
                //     return ''
                // }
                const index =
                  seriesConfig.row -
                  Math.round(
                    (seriesConfig.row *
                      (value - newSeries.yAxis.oldInterval[0])) /
                      (newSeries.yAxis.oldInterval[1] -
                        newSeries.yAxis.oldInterval[0])
                  );

                if (
                  index > newSeries.yAxis.timeStamps.length - 1 ||
                  index < 0 ||
                  newSeries.yAxis.timeStamps.length === 0
                ) {
                  return "";
                }
                const timeStamp =
                  newSeries.yAxis.timeStamps[
                    newSeries.yAxis.timeStamps.length - 1 - index
                  ];

                if (!timeStamp) {
                  return "";
                }
                if (seriesConfig.timeStampFormatter === "hh:mm:ss") {
                  const date = new Date(timeStamp);
                  const hour =
                    date.getHours().toString().length > 1
                      ? date.getHours()
                      : "0" + date.getHours();
                  const minutes =
                    date.getMinutes().toString().length > 1
                      ? date.getMinutes()
                      : "0" + date.getMinutes();
                  const seconds =
                    date.getSeconds().toString().length > 1
                      ? date.getSeconds()
                      : "0" + date.getSeconds();
                  return hour + ":" + minutes + ":" + seconds;
                } else if (seriesConfig.timeStampFormatter === "mm:ss") {
                  const date = new Date(timeStamp);
                  const minutes =
                    date.getMinutes().toString().length > 1
                      ? date.getMinutes()
                      : "0" + date.getMinutes();
                  const seconds =
                    date.getSeconds().toString().length > 1
                      ? date.getSeconds()
                      : "0" + date.getSeconds();
                  return minutes + ":" + seconds;
                }
              },
              color: {
                r: seriesConfig.axisColor.r,
                g: seriesConfig.axisColor.g,
                b: seriesConfig.axisColor.b,
                a: seriesConfig.axisColor.a,
              },
              timeStamps: [],
              points: [],
              words: [],
              markLines: [],
            },
            color: {
              r: 0,
              g: 1,
              b: 0,
              a: 1,
            },
            // 折线数据
            lines: [],
            dragType: "zoom",
            rectMarkZone: [],
            rectMarkZonepoints: [],
            timeMeasureOpen: false,
            timeMeasure: null,
            // 最小值
            min: 0,
            // 最大值
            max: 255,
            // 色带
            waterColors: null,
            showColors: seriesConfig.showColors,
            showAllData: seriesConfig.showAllData,
            measureTextColor: seriesConfig.measureTextColor,
            // 是否允许缩放
            allowZoom: true,
            // 是否在鼠标在图标内滚轮滚动时缩放y轴
            zoomYAxisInMouseWheelOnSerires:
              seriesConfig.zoomYAxisInMouseWheelOnSerires,
            mouseStrapMeasure: null
          };
          const throttleOnXIntervalChange = throttle(() => {
            // if(newSeries.xAxis.onXIntervalChange){
            _doOnXIntervalChange(newSeries, [
              newSeries.xAxis.interval[0],
              newSeries.xAxis.interval[1],
            ]);
            // }
          }, 100);
          newSeries.throttleOnXIntervalChange = throttleOnXIntervalChange;
          _Series.push(newSeries);

          return {
            changeShowAllData(bool) {
              newSeries.showAllData = bool;
            },
            addTooltip(tooltip) {
              newSeries.tooltip = tooltip;
            },
            setTitle(title) {
              newSeries.title = title;
            },
            setXAxis(axisXUnits) {
              newSeries.axisXUnits = axisXUnits;
            },
            setColumn(newColumn) {
              const imageNum = parseInt(newColumn / _maxPointNum) + 1;

              newSeries.column = newColumn;

              const imageColumnPerImage = parseInt(newColumn / imageNum);

              let tmp = 0;
              _imageList = [];
              for (let i = 0; i < imageNum; i++) {
                let imageColumn = imageColumnPerImage;
                if (i == imageNum - 1) {
                  imageColumn = newColumn - tmp;
                }
                tmp += imageColumnPerImage;
                const Unit8Num = newSeries.row * imageColumn * 4;
                const imageDataUnit8 = new Uint8Array(Unit8Num);

                for (let i = 0; i < newSeries.row * imageColumn; i++) {
                  imageDataUnit8[i * 4] = 0;
                  imageDataUnit8[i * 4 + 1] = 0;
                  imageDataUnit8[i * 4 + 2] = 0;
                  imageDataUnit8[i * 4 + 3] = 255;
                }
                _imageList.push({
                  imageDataUnit8: imageDataUnit8,
                  imageColumn: imageColumn,
                });
              }
            },
            setXAxisMarkFormatter(newXAxisMarkFormatter) {
              newSeries.xAxis.xAxisMarkFormatter = newXAxisMarkFormatter;
              _clearCaculatedData();
            },
            setOnClickListener(listener) {
              newSeries.onclickListener = listener;
            },
            setOnMouseMoveListener(listener) {
              newSeries.onMouseMoveListener = listener;
            },
            setOnMeasureListener(listener) {
              newSeries.onMeasureListener = listener;
            },
            addRowData(row, timeStamp) {
              newSeries.yAxis.timeStamps.push(timeStamp);
              newSeries.data = row;
              if (newSeries.timeMeasureOpen && newSeries.timeMeasure) {
                newSeries.timeMeasure.words = [];
              }
              if(newSeries.mouseStrapMeasure && newSeries.mouseStrapMeasure.points && newSeries.mouseStrapMeasure.points.length > 0){
                newSeries.mouseStrapMeasure.words = []
              }
              if (newSeries.yAxis.timeStamps.length > newSeries.row + 1) {
                newSeries.yAxis.timeStamps.splice(0, 1);
              }
              if (!newSeries.colors) {
                newSeries.colors = [
                  {
                    value: 0,
                    color: { r: 0, g: 0, b: 0 },
                  },
                  {
                    value: 255 * (1 / 5),
                    color: { r: 51, g: 0, b: 0 },
                  },
                  {
                    value: 255 * (2 / 5),
                    color: { r: 89, g: 0, b: 0 },
                  },
                  {
                    value: 255 * (3 / 5),
                    color: { r: 89, g: 0, b: 0 },
                  },
                  {
                    value: 255 * (4 / 5),
                    color: { r: 142, g: 0, b: 0 },
                  },
                  {
                    value: 255 * (5 / 5),
                    color: { r: 255, g: 0, b: 0 },
                  },
                ];
              }
              // 填充图片数据
              _imageList.forEach((image, index) => {
                const colors = newSeries.colors;
                // 新一行的数据 （图片cloumn数量乘以4）
                const newData = new Uint8Array(image.imageColumn * 4);
                const startNum = index * image.imageColumn * 2;

                const endNum = startNum + image.imageColumn * 2;
                // console.log("从" + startNum + "开始读取到" + endNum)
                for (let i = startNum; i < endNum; i += 2) {
                  const x = row[i];
                  const y = row[i + 1];
                  // 计算颜色

                  // 计算颜色
                  const startPosition = _searchColor(colors, y);
                  // const temRGB = _getRGB(colors, y)
                  const pos = (i / 2 - startNum / 2) * 4;
                  const pos2 = (i / 2 - startNum / 2) * 4 + 1;
                  const pos3 = (i / 2 - startNum / 2) * 4 + 2;
                  const pos4 = (i / 2 - startNum / 2) * 4 + 3;
                  if (y === -1) {
                    newData[pos] = 0;
                    newData[pos2] = 0;
                    newData[pos3] = 0;
                    newData[pos4] = 255;
                  } else {
                    newData[pos] = colors[startPosition].color.r;
                    newData[pos2] = colors[startPosition].color.g;
                    newData[pos3] = colors[startPosition].color.b;
                    newData[pos4] = 255;
                    /* newData[pos] = temRGB.r
                                        newData[pos2] = temRGB.g
                                        newData[pos3] = temRGB.b
                                        newData[pos4] = 255 */
                  }
                }
                // 后移
                image.imageDataUnit8.copyWithin(
                  image.imageColumn * 4,
                  -(newSeries.row * image.imageColumn * 4),
                  -image.imageColumn * 4
                );
                // 将第一行的数据放入
                image.imageDataUnit8.set(newData, 0);
              });

              // y坐标加一
              // newSeries.yAxis.interval[0] = newSeries.yAxis.interval[0] + 1
              // newSeries.yAxis.interval[1] = newSeries.yAxis.interval[1] + 1
              if (newSeries.direction === "topToBottom") {
                newSeries.yAxis.points = [];
                newSeries.yTablePoints = [];
              }
              if (newSeries.direction === "rightToLeft") {
                newSeries.xAxis.points = [];
                newSeries.xTablePoints = [];
              }
              newSeries.rectMarkZonepoints = [];
              // newSeries.rectMarkZone.forEach((markZone) => {
              //   markZone.transformedData = []
              // })
            },
            getYData(x) {
              const lineData = newSeries.data;
              let y = null;
              // 计算索引 => 更新了算法，占的比例不应该是点数的，而应该是间隔数的
              if (lineData.length && lineData.length > 0) {
                const index = Number(
                  (
                    ((x - lineData[0]) /
                      (lineData[lineData.length - 2] - lineData[0])) *
                    (lineData.length / 2 - 1)
                  ).toFixed(0)
                );
                y = lineData[2 * index + 1];
              }
              if (isNaN(y)) y = null;
              return y;
            },
            addRowDataNoXData(row, timeStamp) {
              newSeries.yAxis.timeStamps.push(timeStamp);
              newSeries.data = row;
              if (newSeries.timeMeasureOpen && newSeries.timeMeasure) {
                newSeries.timeMeasure.words = [];
              }
              if(newSeries.mouseStrapMeasure && newSeries.points && newSeries.points.length > 0){
                newSeries.mouseStrapMeasure.words = []
              }
              if (newSeries.yAxis.timeStamps.length > newSeries.row + 1) {
                newSeries.yAxis.timeStamps.splice(0, 1);
              }
              if (!newSeries.colors) {
                newSeries.colors = [
                  {
                    value: 0,
                    color: { r: 0, g: 0, b: 0 },
                  },
                  {
                    value: 255 * (1 / 5),
                    color: { r: 51, g: 0, b: 0 },
                  },
                  {
                    value: 255 * (2 / 5),
                    color: { r: 89, g: 0, b: 0 },
                  },
                  {
                    value: 255 * (3 / 5),
                    color: { r: 89, g: 0, b: 0 },
                  },
                  {
                    value: 255 * (4 / 5),
                    color: { r: 142, g: 0, b: 0 },
                  },
                  {
                    value: 255 * (5 / 5),
                    color: { r: 255, g: 0, b: 0 },
                  },
                ];
              }
              // 填充图片数据
              _imageList.forEach((image, index) => {
                const colors = newSeries.colors;
                // 新一行的数据 （图片cloumn数量乘以4）
                const newData = new Uint8Array(image.imageColumn * 4);
                const startNum = index * image.imageColumn;

                const endNum = startNum + image.imageColumn;
                // console.log("从" + startNum + "开始读取到" + endNum)
                for (let i = startNum; i < endNum; i++) {
                  const y = row[i];
                  // 计算颜色

                  // 计算颜色
                  const startPosition = _searchColor(colors, y);
                  const pos = (i - startNum) * 4;
                  const pos2 = (i - startNum) * 4 + 1;
                  const pos3 = (i - startNum) * 4 + 2;
                  const pos4 = (i - startNum) * 4 + 3;
                  if (y === -1) {
                    newData[pos] = 0;
                    newData[pos2] = 0;
                    newData[pos3] = 0;
                    newData[pos4] = 255;
                  } else {
                    newData[pos] = colors[startPosition].color.r;
                    newData[pos2] = colors[startPosition].color.g;
                    newData[pos3] = colors[startPosition].color.b;
                    newData[pos4] = 255;
                  }
                }
                // 后移
                image.imageDataUnit8.copyWithin(
                  image.imageColumn * 4,
                  -(newSeries.row * image.imageColumn * 4),
                  -image.imageColumn * 4
                );
                // 将第一行的数据放入
                image.imageDataUnit8.set(newData, 0);
              });

              // y坐标加一
              // newSeries.yAxis.interval[0] = newSeries.yAxis.interval[0] + 1
              // newSeries.yAxis.interval[1] = newSeries.yAxis.interval[1] + 1
              if (newSeries.direction === "topToBottom") {
                newSeries.yAxis.points = [];
                newSeries.yTablePoints = [];
              }
              if (newSeries.direction === "rightToLeft") {
                newSeries.xAxis.points = [];
                newSeries.xTablePoints = [];
              }
              newSeries.rectMarkZonepoints = [];
              // newSeries.rectMarkZone.forEach((markZone) => {
              //   markZone.transformedData = []
              // })
            },
            /**
             * 清空数据
             */
            clearData() {
              _imageList.forEach((image) => {
                const Unit8Num = newSeries.row * image.imageColumn * 4;
                image.imageDataUnit8 = new Uint8Array(Unit8Num);
                for (let i = 0; i < newSeries.row * image.imageColumn; i++) {
                  image.imageDataUnit8[i * 4] = 0;
                  image.imageDataUnit8[i * 4 + 1] = 0;
                  image.imageDataUnit8[i * 4 + 2] = 0;
                  image.imageDataUnit8[i * 4 + 3] = 255;
                }
              });
              newSeries.yAxis.timeStamps = [];
              newSeries.yAxis.interval = [-seriesConfig.row, 0];
              _clearCaculatedData();
              _refresh();
            },
            /**
             * 设置最大最小value(影响颜色)
             */
            setValueInterval(min, max) {
              newSeries.min = min;
              newSeries.max = max;
              if (!newSeries.waterColors) {
                const tmp = [];
                const zcColors = waterColor.zcColors();
                for (let i = 0; i < zcColors.length; i++) {
                  tmp.push(zcColors[zcColors.length - 1 - i]);
                }
                newSeries.waterColors = tmp;
              }
              const interval = newSeries.max - newSeries.min;
              const colors = [];
              newSeries.waterColors.forEach((waterColor, index) => {
                colors.push({
                  value:
                    min + interval * (index / newSeries.waterColors.length),
                  color: {
                    r: waterColor.R,
                    g: waterColor.G,
                    b: waterColor.B,
                  },
                });
              });
              newSeries.colors = colors;
            },
            setMaxXInterval(newInterval) {
              newSeries.xAxis.interval = [newInterval[0], newInterval[1]];
              newSeries.xAxis.oldInterval = [newInterval[0], newInterval[1]];
              _clearCaculatedData();
            },
            changeXInterval(newInterval) {
              newSeries.xAxis.interval = newInterval;
              _clearCaculatedData();
            },
            setOnXIntervalChange(listener) {
              newSeries.xAxis.onXIntervalChange = listener;
            },
            addRectMarkZone(startX, endX, startY, endY, str) {
              // 传入的是时间戳,需要转化成坐标
              let realStartY = -1;
              for (let i = 0; i < newSeries.yAxis.timeStamps.length; i++) {
                if (startY < newSeries.yAxis.timeStamps[i]) {
                  if (i - 1 >= 0) {
                    realStartY = i - 1;
                  }
                  break;
                }
              }
              let realEndY = -1;
              for (let i = 0; i < newSeries.yAxis.timeStamps.length; i++) {
                if (endY < newSeries.yAxis.timeStamps[i]) {
                  if (i - 1 >= 0) {
                    realEndY = i - 1;
                  }
                  break;
                }
              }
              if (realStartY < 0 || realEndY < 0) {
                return;
              }
              // 之前的值只表示y坐标在axis.row中的排名位置 所以需要加上interval[0],算出实际value
              realStartY = newSeries.yAxis.interval[0] + realStartY;
              realEndY = newSeries.yAxis.interval[0] + realEndY;
              newSeries.rectMarkZone.push({
                startX: startX,
                endX: endX,
                startY: realStartY,
                endY: realEndY,
                str: str,
                // startY: startY,
                // endY: endY,
                transformedData: [],
              });
              // newSeries.rectMarkZonepoints = []
            },
            clearRectMarkZone() {
              newSeries.rectMarkZone = [];
              newSeries.rectMarkZonepoints = [];
            },
            changeDrageType(type) {
              if (type === "zoom" || type === "measure") {
                newSeries.dragType = type;
              }
            },
            setTimeMeasureOpen(timeMeasureOpen) {
              if (timeMeasureOpen) {
                // newSeries.dragType = 'measure'
                newSeries.dragType = "zoom";
                newSeries.timeMeasureOpen = timeMeasureOpen;
                // 打开时间测量的时候框选一个默认区域
                if (newSeries.timeMeasure) {
                  return;
                }
                const startX = _container.clientWidth / 2 - 50;
                const endX = _container.clientWidth / 2 + 50;
                const startY = _container.clientHeight / 2 - 50;
                const endY = _container.clientHeight / 2 + 50;

                // 计算时间
                newSeries.timeMeasure = {
                  type: "time",
                  startX: startX,
                  endX: endX,
                  startY: startY,
                  endY: endY,
                  words: [],
                };
              } else {
                newSeries.dragType = "zoom";
                newSeries.timeMeasureOpen = timeMeasureOpen;
              }
            },
            setColors(waterColors) {
              const interval = newSeries.max - newSeries.min;
              const tmp = [];
              for (let i = 0; i < waterColors.length; i++) {
                tmp.push(waterColors[waterColors.length - 1 - i]);
              }
              newSeries.waterColors = tmp;
              const colors = [];
              newSeries.waterColors.forEach((waterColor, index) => {
                colors.push({
                  value:
                    newSeries.min + interval * (index / waterColors.length),
                  color: {
                    r: waterColor.R / 255,
                    g: waterColor.G / 255,
                    b: waterColor.B / 255,
                  },
                });
              });
              newSeries.colors = colors;
            },
            setAllowZoom(allowZoom) {
              newSeries.allowZoom = allowZoom;
            },
            clearMouseStrapMeasure(){
              newSeries.mouseStrapMeasure = null;
              _refresh();
            }
          };
        },
        /**
         * 刷新当前图表
         */
        refresh() {
          _refresh();
        },
        reSize() {
          const div = document.querySelector("#" + _config.container);
          _container.width = div.clientWidth;
          _container.height = div.clientHeight;
          _textcontainer.width = div.clientWidth;
          _textcontainer.height = div.clientHeight;
          _textCtx.width = div.clientWidth;
          _textCtx.height = div.clientHeight;
          _clearCaculatedData();
          // 清空计算矩阵
          _axisMatrix = null;
          _Series.forEach((series) => {
            series._linesMatrix = null;
            // 清空axis标记  的文字缓存
            series.xAxis.points = [];
            series.yAxis.points = [];
          });
          _refresh();
        },
      };
    },
    /**
     * 折线图
     */
    lineChart(config) {
      _config = {
        type: "line",
        container: config.container,
        drawCenterLine:
          config.drawCenterLine == undefined ? true : config.drawCenterLine,
        background:
          config.background != null
            ? config.background
            : {
                r: 0,
                g: 0,
                b: 0,
              },
      };
      _initGl();
      // 添加鼠标监听
      _addMouseEventListener();
      return {
        /**
         * 添加新的线
         * seriesConfig
         *
         */
        addSeries(seriesConfig) {
          if (!seriesConfig) {
            seriesConfig = {
              xAxisInterval: [0, 100],
              xAxisPadding: 30,
              xAxisAnotherPadding: 10,
              xAxisMarkNum: 5,
              yAxisInterval: [0, 100],
              yAxisPadding: 30,
              yAxisAnotherPadding: 30,
              yAxisMarkNum: 5,
              zoomYAxisInMouseWheelOnSerires: false,
              axisColor: {
                r: 1,
                g: 1,
                b: 1,
                a: 1,
              },
              measureTextColor: {
                r: 1,
                g: 1,
                b: 1,
                a: 1,
              },
              showMarkZoneWord: true,
            };
          } else {
            seriesConfig = {
              title: seriesConfig.title
                ? seriesConfig.title
                : { text: "", top: 0, left: 0 },
              axisXUnits: seriesConfig.axisXUnits
                ? seriesConfig.axisXUnits
                : { text: "", top: 0, left: 0 },
              axisYUnits: seriesConfig.axisYUnits
                ? seriesConfig.axisYUnits
                : { text: "", top: 0, left: 0 },
              tooltip: seriesConfig.tooltip
                ? seriesConfig.tooltip
                : { value1: "", value2: "", top: 0, left: 0 },
              xAxisInterval: seriesConfig.xAxisInterval
                ? seriesConfig.xAxisInterval
                : [0, 100],
              xAxisPadding: seriesConfig.xAxisPadding
                ? seriesConfig.xAxisPadding
                : 30,
              xAxisAnotherPadding:
                seriesConfig.xAxisAnotherPadding != null
                  ? seriesConfig.xAxisAnotherPadding
                  : 30,
              xAxisMarkNum: seriesConfig.xAxisMarkNum
                ? seriesConfig.xAxisMarkNum
                : 5,
              xAxisMarkFormatter: seriesConfig.xAxisMarkFormatter,
              yAxisInterval: seriesConfig.yAxisInterval
                ? seriesConfig.yAxisInterval
                : [0, 100],
              yAxisPadding: seriesConfig.yAxisPadding
                ? seriesConfig.yAxisPadding
                : 30,
              yAxisAnotherPadding: seriesConfig.yAxisAnotherPadding
                ? seriesConfig.yAxisAnotherPadding
                : 30,
              yAxisMarkNum: seriesConfig.yAxisMarkNum
                ? seriesConfig.yAxisMarkNum
                : 5,
              yAxisMarkFormatter: seriesConfig.yAxisMarkFormatter,
              minXInterval: seriesConfig.minXInterval,
              axisColor: seriesConfig.axisColor
                ? seriesConfig.axisColor
                : {
                    r: 1,
                    g: 1,
                    b: 1,
                    a: 1,
                  },
              measureTextColor: seriesConfig.measureTextColor
                ? seriesConfig.measureTextColor
                : {
                    r: 1,
                    g: 1,
                    b: 1,
                    a: 1,
                  },
              showMarkZoneWord:
                seriesConfig.showMarkZoneWord != null
                  ? seriesConfig.showMarkZoneWord
                  : true,
              zoomYAxisInMouseWheelOnSerires:
                seriesConfig.zoomYAxisInMouseWheelOnSerires != null
                  ? seriesConfig.zoomYAxisInMouseWheelOnSerires
                  : false,
            };
          }
          const newSeries = {
            title: seriesConfig.title,
            axisXUnits: seriesConfig.axisXUnits,
            axisYUnits: seriesConfig.axisYUnits,
            tooltip: seriesConfig.tooltip,
            xAxis: {
              interval: seriesConfig.xAxisInterval,
              oldInterval: [
                seriesConfig.xAxisInterval[0],
                seriesConfig.xAxisInterval[1],
              ],
              padding: seriesConfig.xAxisPadding,
              defaltPadding: seriesConfig.xAxisAnotherPadding,
              markNum: seriesConfig.xAxisMarkNum, // 刻度数量
              xAxisMarkFormatter: seriesConfig.xAxisMarkFormatter,
              minXInterval: seriesConfig.minXInterval,
              color: {
                r: seriesConfig.axisColor.r,
                g: seriesConfig.axisColor.g,
                b: seriesConfig.axisColor.b,
                a: seriesConfig.axisColor.a,
              },
              points: [],
              words: [],
              markLines: [],
              markZones: [],
              markZonesHighLight: [],
              markZonesOfBlackList: [],
              showMarkZoneWord: seriesConfig.showMarkZoneWord,
            },
            yAxis: {
              interval: seriesConfig.yAxisInterval,
              oldInterval: [
                seriesConfig.yAxisInterval[0],
                seriesConfig.yAxisInterval[1],
              ],
              padding: seriesConfig.yAxisPadding,
              defaltPadding: seriesConfig.yAxisAnotherPadding,
              markNum: seriesConfig.yAxisMarkNum,
              yAxisMarkFormatter: seriesConfig.yAxisMarkFormatter,
              color: {
                r: seriesConfig.axisColor.r,
                g: seriesConfig.axisColor.g,
                b: seriesConfig.axisColor.b,
                a: seriesConfig.axisColor.a,
              },
              points: [],
              words: [],
              markLines: [],
            },
            color: {
              r: 0,
              g: 1,
              b: 0,
              a: 1,
            },
            // 折线数据
            lines: [],
            dragType: "zoom",
            SNRMeasureOpen: false,
            SNRMeasure: null,
            freqMeasureOpen: false,
            freqMeasure: null,
            kdSelectOpen: false,
            kdSelect: null,
            kdCollectionWidth: 100,
            measureTextColor: seriesConfig.measureTextColor,
            // 是否允许缩放
            allowZoom: true,
            // 是否在鼠标在图标内滚轮滚动时缩放y轴
            zoomYAxisInMouseWheelOnSerires:
              seriesConfig.zoomYAxisInMouseWheelOnSerires,
            mouseStrapMeasure: null
          };
          _Series.push(newSeries);
          const throttleOnXIntervalChange = throttle(() => {
            // if(newSeries.xAxis.onXIntervalChange){
            _doOnXIntervalChange(newSeries, [
              newSeries.xAxis.interval[0],
              newSeries.xAxis.interval[1],
            ]);
            // }
          }, 100);
          newSeries.throttleOnXIntervalChange = throttleOnXIntervalChange;
          return {
            addLine(lineConfig) {
              if (!lineConfig) {
                lineConfig = {
                  color: {
                    r: 1,
                    g: 1,
                    b: 1,
                  },
                };
              }
              const newLine = {
                data: [],
                transferedData: [],
                color: {
                  r: lineConfig.color.r,
                  g: lineConfig.color.g,
                  b: lineConfig.color.b,
                  a: 1,
                },
                visible: true,
              };
              newSeries.lines.push(newLine);
              return {
                setData(newData) {
                  newLine.data = newData;
                  newLine.transferedData = [];
                },
                setVisible(visible) {
                  newLine.visible = visible;
                },
                // 扫频数据用于计算X坐标对应的Y值
                getYData(x, index) {
                  /* const temIndex = index || 0
                                    const lineData = _Series[0].lines[temIndex].data
                                    let y = null
                  
                                    // 优化逻辑 => 从两个循环变成了一个循环寻找对应x的y值
                                    for (let index = 0; index < lineData.length; index += 2) {
                                      if (index !== lineData.length - 1) {
                                        if (x >= lineData[index] && x <= lineData[index + 2]) {
                                          y = lineData[index + 1]
                                          break
                                        }
                                      } else {
                                        if (x <= lineData[index] && x >= lineData[index - 2]) {
                                          y = lineData[index + 1]
                                          break
                                        }
                                      }
                                    }
                                    if (isNaN(y)) y = null
                                    return y
                                    */
                  const temIndex = index || 0;
                  const lineData = _Series[0].lines[temIndex].data;
                  let y = null;
                  let index1;
                  // console.log('lineData[0]', lineData[0])
                  // 计算索引 => 更新了算法，占的比例不应该是点数的，而应该是间隔数的
                  if (lineData.length && lineData.length > 0) {
                    const index = Number(
                      (
                        ((x - lineData[0]) /
                          (lineData[lineData.length - 2] - lineData[0])) *
                        (lineData.length / 2 - 1)
                      ).toFixed(0)
                    );
                    index1 = index;
                    y = lineData[2 * index + 1];
                  }
                  if (isNaN(y)) y = null;
                  // console.log('悬停值', x, y, lineData)

                  return y;
                },
                getIndex(x, index) {
                  const temIndex = index || 0;
                  const lineData = _Series[0].lines[temIndex].data;
                  let index1;
                  // console.log('lineData[0]', lineData[0])
                  // 计算索引 => 更新了算法，占的比例不应该是点数的，而应该是间隔数的
                  if (lineData.length && lineData.length > 0) {
                    const index = Number(
                      (
                        ((x - lineData[0]) /
                          (lineData[lineData.length - 2] - lineData[0])) *
                        (lineData.length / 2 - 1)
                      ).toFixed(0)
                    );
                    index1 = index;
                  }
                  return index1;
                },
              };
            },
            addTooltip(tooltip) {
              newSeries.tooltip = tooltip;
            },
            setTitle(title) {
              newSeries.title = title;
            },
            setXAxis(axisXUnits) {
              newSeries.axisXUnits = axisXUnits;
            },
            setMaxXInterval(newInterval) {
              newSeries.xAxis.interval = newInterval;
              newSeries.xAxis.oldInterval = [newInterval[0], newInterval[1]];
              _clearCaculatedData();
              // 清空
              if (newSeries.kdCollection) {
                // newSeries.kdCollection.points = []
                newSeries.kdCollection = null;
              }
            },
            setMaxXIntervalOnly(newInterval) {
              // newSeries.xAxis.interval = newInterval
              // //console.log(newInterval)
              newSeries.xAxis.oldInterval = [newInterval[0], newInterval[1]];
              if (
                newSeries.xAxis.interval[0] < newInterval[0] ||
                newSeries.xAxis.interval[1] > newInterval[1]
              ) {
                newSeries.xAxis.interval = newInterval;
              }
              _clearCaculatedData();
            },
            changeXInterval(newInterval) {
              newSeries.xAxis.interval = newInterval;
              _clearCaculatedData();
            },
            setMaxYInterval(newInterval) {
              newSeries.yAxis.interval = newInterval;
              newSeries.yAxis.oldInterval = [newInterval[0], newInterval[1]];
              _clearCaculatedData();
            },
            setXAxisMarkFormatter(newXAxisMarkFormatter) {
              newSeries.xAxis.xAxisMarkFormatter = newXAxisMarkFormatter;
              _clearCaculatedData();
            },
            getXInterval() {
              return [newSeries.xAxis.interval[0], newSeries.xAxis.interval[1]];
            },
            getMaxXInterval() {
              return [
                newSeries.xAxis.oldInterval[0],
                newSeries.xAxis.oldInterval[1],
              ];
            },
            changeYInterval(newInterval) {
              newSeries.yAxis.interval = newInterval;
              _clearCaculatedData();
            },
            // 重置y轴为初始值
            resumeYInterval() {
              newSeries.yAxis.interval = [
                newSeries.yAxis.oldInterval[0],
                newSeries.yAxis.oldInterval[1],
              ];
              _clearCaculatedData();
            },
            getYInterval() {
              return [newSeries.yAxis.interval[0], newSeries.yAxis.interval[1]];
            },
            setOnXIntervalChange(onXIntervalChange) {
              newSeries.xAxis.onXIntervalChange = onXIntervalChange;
            },
            addYMarkLine(yValue, color) {
              const markLine = {
                id: new Date().getTime() + "," + _markIdIdx++,
                value: yValue,
                pixes: -9999999999,
                points: [],
                type: "y",
                color: {
                  r: color ? color.r : 1,
                  g: color ? color.g : 1,
                  b: color ? color.b : 1,
                },
              };
              newSeries.yAxis.markLines.push(markLine);
              return {
                setOnValueChangeListener(listener) {
                  markLine.onValueChangeListener = listener;
                },
                /**
                 * 从series中删除当前markline
                 */
                remove() {
                  for (let i = 0; i < newSeries.xAxis.markLines.length; i++) {
                    const target = newSeries.xAxis.markLines[i];
                    if (target.id === markLine.id) {
                      newSeries.xAxis.markLines.splice(i, 1);
                      return;
                    }
                  }
                  for (let i = 0; i < newSeries.yAxis.markLines.length; i++) {
                    const target = newSeries.yAxis.markLines[i];
                    if (target.id === markLine.id) {
                      newSeries.yAxis.markLines.splice(i, 1);
                      return;
                    }
                  }
                },
              };
            },
            addXMarkLine(xValue, color) {
              const markLine = {
                id: new Date().getTime() + "," + _markIdIdx++,
                visible: true,
                value: xValue,
                pixes: -9999999999,
                points: [],
                type: "x",
                color: {
                  r: color ? color.r : 1,
                  g: color ? color.g : 1,
                  b: color ? color.b : 1,
                },
              };
              newSeries.xAxis.markLines.push(markLine);
              return {
                setOnValueChangeListener(listener) {
                  markLine.onValueChangeListener = listener;
                },
                setOnMouseUpListener(listener) {
                  markLine.onMouseUpListener = listener;
                },
                /**
                 * 从series中删除当前markline
                 */
                remove() {
                  for (let i = 0; i < newSeries.xAxis.markLines.length; i++) {
                    const target = newSeries.xAxis.markLines[i];
                    if (target.id === markLine.id) {
                      newSeries.xAxis.markLines.splice(i, 1);
                      return;
                    }
                  }
                  for (let i = 0; i < newSeries.yAxis.markLines.length; i++) {
                    const target = newSeries.yAxis.markLines[i];
                    if (target.id === markLine.id) {
                      newSeries.yAxis.markLines.splice(i, 1);
                      return;
                    }
                  }
                },
                setVisible(visible) {
                  markLine.visible = visible;
                },
                setValue(value) {
                  markLine.value = value;
                  markLine.points = [];
                },
              };
            },
            setOnClickListener(listener) {
              newSeries.onclickListener = listener;
            },
            setOnMouseMoveListener(listener) {
              newSeries.onMouseMoveListener = listener;
            },
            setOnMouseLeaveListener(listener) {
              newSeries.onMouseLeaveListener = listener;
            },
            setOnMeasureListener(listener) {
              newSeries.onMeasureListener = listener;
            },
            setShowMarkZoneWord(showMarkZoneWord) {
              newSeries.xAxis.showMarkZoneWord = showMarkZoneWord;
            },
            /**
             * 添加mark
             * @param {*} start
             * @param {*} end
             * @param {*} str
             * @param {*} color
             */
            addXMarkZone(start, end, str, color) {
              newSeries.xAxis.markZones.push({
                start: start,
                end: end,
                points: [],
                str: str,
                color: color,
              });
            },
            /**
             * 添加选中状态的mark （就是有白色左右边框）
             * @param {*} start
             * @param {*} end
             * @param {*} str
             * @param {*} color
             * @param {*} type
             */
            addXMarkZoneFocus(start, end, str, color) {
              newSeries.xAxis.markZones.push({
                start: start,
                end: end,
                points: [],
                str: str,
                color: color,
                borderColor: {
                  r: 255 / 255,
                  g: 255 / 255,
                  b: 255 / 255,
                  a: 1,
                },
              });
            },
            addXMarkZoneHighLight(start, end, str) {
              newSeries.xAxis.markZonesHighLight.push({
                start: start,
                end: end,
                points: [],
                str: str,
              });
            },
            /**
             * 添加黑名单的mark
             * @param {*} start
             * @param {*} end
             * @param {*} str
             */
            addXMarkZoneOfBlackList(start, end, str, color) {
              newSeries.xAxis.markZonesOfBlackList.push({
                start: start,
                end: end,
                points: [],
                str: str,
                color: color,
              });
            },
            /**
             * 清空所有mark
             */
            clearXmarkZone() {
              newSeries.xAxis.markZones = [];
              newSeries.xAxis.markZonePoints = [];
              newSeries.xAxis.markZonePointColors = [];
              newSeries.xAxis.markZoneLRPoints = [];
              newSeries.xAxis.markZoneLRPointsColors = [];
            },
            clearXmarkZoneOfBlackList() {
              newSeries.xAxis.markZonesOfBlackList = [];
              newSeries.xAxis.markZonesOfBlackListPoints = [];
              newSeries.xAxis.markZonesOfBlackListPointColors = [];
              newSeries.xAxis.markZonesOfBlackListLRPoints = [];
              newSeries.xAxis.markZonesOfBlackListLRPointsColors = [];
            },
            clearXmarkZoneHighLight() {
              newSeries.xAxis.markZonesHighLight = [];
            },
            changeDrageType(type) {
              if (type === "zoom" || type === "measure") {
                newSeries.dragType = type;
              }
            },
            setSNRMeasureOpen(SNRMeasureOpen) {
              newSeries.SNRMeasureOpen = SNRMeasureOpen;
            },
            setFreqMeasureOpen(freqMeasureOpen) {
              newSeries.freqMeasureOpen = freqMeasureOpen;
            },
            setKdCollection(kdCollectionOpen, kdCollectionWidth) {
              newSeries.kdCollection = null;
              newSeries.kdCollectionOpen = kdCollectionOpen;
              newSeries.kdCollectionWidth = kdCollectionWidth;
              _refresh();
            },
            setKdCollectionListener(kdCollectionListener) {
              newSeries.kdCollectionListener = kdCollectionListener;
            },
            getKdCollectionValue() {
              return newSeries.kdCollection
                ? newSeries.kdCollection.kdCollectionPositionValue
                : null;
            },
            setMouseClickPosition(x, y, xstr, ystr, infoStr) {
              const series = _Series[0];
              const yPixes = _getYPixesByYvalue(y, series);
              const xPixes = _getXPixesByXvalue(x, series);
              const mouseClickMarkPoints = [
                series.yAxis.padding,
                yPixes,
                _container.clientWidth - series.yAxis.defaltPadding,
                yPixes,
                xPixes,
                series.xAxis.padding,
                xPixes,
                _container.clientHeight - series.xAxis.defaltPadding,
              ];
              series.mouseClickMarkPoints = mouseClickMarkPoints;

              if (xstr && ystr) {
                // 设置悬浮文字
                series.mouseClickMarkWords = [
                  {
                    str: xstr,
                    x: xPixes + 10,
                    y: _container.height - yPixes + 15 + 5,
                  },
                  {
                    str: ystr,
                    x: xPixes + 10,
                    y: _container.height - yPixes + 37 + 5,
                  }/* ,
                  {
                    str: infoStr,
                    x: xPixes + 10,
                    y: _container.height - yPixes + 59 + 5,
                  }, */
                ];
              } else {
                series.mouseClickMarkWords = [];
              }
              _refresh();
            },
            setOnYIntervalChange(onYIntervalChange) {
              newSeries.yAxis.onYIntervalChange = onYIntervalChange;
            },
            setAllowZoom(allowZoom) {
              newSeries.allowZoom = allowZoom;
            },
            clearMouseStrapMeasure(){
              newSeries.mouseStrapMeasure = null;
              _refresh();
            }
          };
        },
        /**
         * 刷新当前图表
         */
        refresh() {
          _refresh();
        },
        reSize() {
          const div = document.querySelector("#" + _config.container);
          _container.width = div.clientWidth;
          _container.height = div.clientHeight;
          _textcontainer.width = div.clientWidth;
          _textcontainer.height = div.clientHeight;
          _textCtx.width = div.clientWidth;
          _textCtx.height = div.clientHeight;
          _clearCaculatedData();
          // 清空计算矩阵
          _axisMatrix = null;
          _Series.forEach((series) => {
            series._linesMatrix = null;
            // 清空axis标记  的文字缓存
            series.xAxis.points = [];
            series.yAxis.points = [];
          });
          _refresh();
        },
      };
    },
  };
};

export default Chart;
